score:0
I am posting the working version of my requirement :)
XDocument currentPermission = XDocument.Parse(xmlParentStr);
XDocument newPermission = XDocument.Load(xmlToAddStr);
int fyValue = 2012, countryId = 205, stateId = 0, cityId = 0;
//check whether user has access for this fiscal year or not
IEnumerable<XElement> fyList = from fyNode in currentPermission.Descendants("FiscalYear")
where (int)fyNode.Attribute("Name") == fyValue
select fyNode;
if (null != fyList && fyList.Count() > 0) //Fiscal year present, means user is trying to modify permissions for the given fiscal year
{
//Check whether user has access for this country or not
IEnumerable<XElement> countryList = from subNode in fyList.Descendants("Country")
where (int)subNode.Attribute("ID") == countryId
select subNode;
if (null != countryList && countryList.Count() > 0) //country present, means user is trying to modify permissions for a country
{
IEnumerable<XElement> stateList = from mbpNode in countryList.Descendants("State")
where (int)mbpNode.Attribute("ID") == stateId
select mbpNode;
if (stateId != 0 && null != stateList && stateList.Count() > 0)
{
IEnumerable<XElement> cityList = from mbpNode in stateList.Descendants("City")
where (int)mbpNode.Attribute("ID") == stateId
select mbpNode;
if (cityId != 0 && null != cityList && cityList.Count() > 0)
{
// User already have access, nothing to do
}
else
{
currentPermission.Elements("FiscalYear")
.Where(t => t.Attribute("Name").Value == fyValue.ToString())
.Elements("Country")
.Where(t => t.Attribute("ID").Value == countryId.ToString())
.Elements("State")
.Where(t => t.Attribute("ID").Value == stateId.ToString())
.Single()
.Add(newPermission.Descendants("City"));
}
}
else
{
currentPermission.Elements("FiscalYear")
.Where(t => t.Attribute("Name").Value == fyValue.ToString())
.Elements("Country")
.Where(t => t.Attribute("ID").Value == countryId.ToString())
.Single()
.Add(newPermission.Descendants("State"));
}
}
else //Country is not present means user is granted permissions for this country
{
currentPermission.Elements("FiscalYear")
.Where(t => t.Attribute("Name").Value == fyValue.ToString())
.Single()
.Add(newPermission.Descendants("Country"));
}
}
else //fiscal year is not present, it means user is trying to add permissions for a new fiscal year
{
//string newPermissionXML = CreatePermissionXML(newUserPermission);
currentPermission.Add(newPermission.Descendants("FiscalYear"));
}
score:1
// untested
var masterDoc = XDocument.Load(...);
var updateDoc = XDocument.Load(...);
foreach (var year in updateDoc.Root.Descendants("FiscalYear"))
{
var oldYear = masterDoc.Root.Descendants("FiscalYear")
.Where(y => y.Attributes["ID"].Value == year.Attributes["ID"].Value)
.FirstOrDefault() ;
if (oldYear == null)
{
masterDoc.Root.Add(new XElement(....));
}
else
{
// nested properties
}
}
score:2
If you simply want to append a new node, this is quite simple:
var xmlDocument = XDocument.Parse(xmlParentStr);
var xmlToAdd = XElement.Parse(xmlToAddStr);
if (null != xmlDocument.Element("Security"))
xmlDocument.Element("Security").AddFirst(xmlToAdd);
Where xmlParentStr is a string that includes the xml that you first present, with a 2011 and 2010 FiscalYear tag. xmlToAdd is the a string with the xml for the fiscal year of 2012. This will give you:
<Security>
<FiscalYear ID="2012">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2011">
<Country ID="23">
<State ID="10">
<City ID="1"></City>
<City ID="3"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2010">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
</Security>
There are various other ways to load the xml into an XDocument or an XElement, by the way. Such as XDocument.Load() and XElement.Load which can pull it in from a FileStream, a URI, or a Reader.
If you then wanted to change the country id for 2011, you could easily do it via:
var elementToChange=xmlDocument
.Descendants()
.Where(x => x.Name.LocalName=="FiscalYear" && x.Attribute("ID")!=null && x.Attribute("ID").Value=="2011");
foreach(var element in elementToChange) {
var changes = element.Descendants().Where(x => x.Name.LocalName == "Country" && x.Attribute("ID").Value == "23");
foreach(var change in changes) {
change.Attribute("ID").SetValue("1337");
}
}
Which would then yield:
<Security>
<FiscalYear ID="2012">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2011">
<Country ID="1337">
<State ID="10">
<City ID="1"></City>
<City ID="3"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2010">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
</Security>
I made the value you need change to "1337" because it's easier to see, but the principle is the same. You can continue to walk down the tree in this manner. (And the below code would change every entry that matches, if you decided to only change the first or know you would only ever have one, you could simplify the above code and get rid of the foreach loops by using .FirstOrDefault())
Source: stackoverflow.com
Related Articles
- Efficient way to merge 2 xmls into a new XML in LINQ
- Merge two List<object> into one List in Linq
- Merge multiple Lists into one List with LINQ
- LINQ merge List<IEnumerable<T>> into one IEnumerable<T> by some rule
- LINQ Source Code Available
- How can I combine this code into one or two LINQ queries?
- Merge duplicate data without affecting others in LINQ code
- How to get SQL query into LINQ form in C# code
- creating Linq to sqlite dbml from DbLinq source code
- How to flatten a multi level XML into a single level XML using c# code LINQ
- Convert piece of code into LINQ (short syntax)
- Can't add a new record with an integer value into database by using linq from code C#
- Dynamic LINQ query string for indexing into IEnumerableObjects for efficient Multidimensional Array sorting
- Merge flat list into hierarchy using LINQ
- How can I code numerous MIN functions into one LINQ to DataSet query
- How to merge two lists while adding metadata indicating value source with LINQ statement?
- replace 3 levels of nested for loops by efficient code possibly linq
- Injecting Code Into Linq
- Merge two LINQ expressions into one
- Efficient way to merge table like datastructure using linq
- Can I can convert this C# code into some Linq code?
- Translating Linq Code Block into SQL
- Efficient conversion of an array into a two-dimensional one using LINQ
- source code for LINQ 101 samples
- Most efficient way of loading data into LINQ object for search result type method
- merge 2 Linq sequences into one, with precedence
- Merge multiple xml files into one using linq to xml
- optimise code into linq expression
- How can i convert this code snippet into LINQ format?
- Merge List<PartialColumn> into <List<Column> using LINQ
- Why I'm still getting System.NotSupportedException
- LINQ - Sum depending on multiple conditions
- Casting/converting an expression back to a lambda of Func<Foo,bool> (after serialization)
- Using LINQ to create a simple login
- Removing taken numbers from a List
- DateTime comparison without time part?
- Search for an integer item in a datatable with string column values
- How do I navigate through multiple relationships using LINQ to Entities?
- Update in LINQ with one trip to database?
- Can I update the UI from a LINQ binding?
- Debugging a complex linq query
- Sequence contains no elements Error
- How to initialize the id of a button with a value from model
- MVC3 cannot display other table value using foreign key
- Linq SELECT AS and CONCAT
- Grouping in LINQ to Entity Model
- Get position of specific element in ordered table
- How to use having ,group by and distinct in linq or lambda expression
- Always Encrypted, LINQ, and Where Contains
- GroupBy with property in a nested child collection