Reputation: 527
i have a xml like following one.
<testing>
<node01 name="node01Name">
<node02s>
<node02 name="1">
<CustomProperties>
<CustomProperty Name="ASCII File Name" Value="index.txt" FilterID="0" />
<CustomProperty Name="ASCII Folder" Value="\\abc\cdf\aaaa" FilterID="0" />
<CustomProperty Name="Delimiter" Value="CommaQuote" FilterID="0" />
<CustomProperty Name="Duplicate Handling" Value="Replace if Dup" FilterID="0" />
<CustomProperty Name="EMAILATTDOC" Value="1" FilterID="0" />
<CustomProperty Name="EMAILATTINDEX" Value="0" FilterID="0" />
<CustomProperty Name="EMAILOUTBODY" FilterID="0" />
<CustomProperty Name="EMAILOUTCC" FilterID="0" />
</CustomProperties>
</node02>
<node02 name="2">
<CustomProperties>
<CustomProperty Name="ASCII File Name" Value="index.txt" FilterID="0" />
<CustomProperty Name="ASCII Folder" Value="\\abc\cdf\aaaa" FilterID="0" />
<CustomProperty Name="Delimiter" Value="CommaQuote" FilterID="0" />
<CustomProperty Name="Duplicate Handling" Value="Replace if Dup" FilterID="0" />
<CustomProperty Name="EMAILATTDOC" Value="1" FilterID="0" />
<CustomProperty Name="EMAILATTINDEX" Value="0" FilterID="0" />
<CustomProperty Name="EMAILOUTBODY" FilterID="0" />
<CustomProperty Name="EMAILOUTCC" FilterID="0" />
</CustomProperties>
</node02>
</node02s>
</node01>
</testing>
I need to get each CustomProperty under each node02. this is my code.
XDocument configparentXML = XDocument.Load("admin.xml");
string node = "node02";
var batchClasses = from batchClasse in configparentXML.Descendants(node)
select new ReadingXmlWithLinq
{
BatchClassName = batchClasse.Attribute("Name") != null ? batchClasse.Attribute("Name").Value : "",
};
foreach (var lv0 in batchClasses)
{
node = "CustomProperty";
var CustomProperties = from CustomProperty in configparentXML.Descendants(node)
select new ReadingXmlWithLinq
{
CustomPropertyName = documentClasse.Attribute("Name") != null ? documentClasse.Attribute("Name").Value : ""
};
}
But in hear its return all CustomPropery Values. How can i get CustomerPropery for a node02 ?
Thank you very much.
Upvotes: 0
Views: 333
Reputation: 120518
I'd approach this with XPath:
var xmlString = @"<testing>...</testing>";
var doc = XDocument.Parse(xmlString);
var nav = doc.CreateNavigator();
var path = "/testing/node01/node02s/node02/CustomProperties/CustomProperty";
var nodeIterator = nav.Select(path);
var nodes =
nodeIterator
.Cast<XPathNavigator>()
.Select(n=>XElement.Parse(n.OuterXml));
EDIT
To get all nodes under (say) <node02 name="2">
you could alter the path as follows:
var path=
"/testing/node01/node02s/node02[@name=2]/CustomProperties/CustomProperty";
Here's a page of XPath examples so you can see what's possible.
Upvotes: 3
Reputation: 134591
It isn't clear to me how you want the data, there's just not enough information here to work with.
Instead, here's an example of how you could select all node02
elements and grab their names and the names of their CustomProperty
's. This selects ALL node02
's and ALL their CustomProperty
's just as your code does. You don't actually filter anything nor did you specify which nodes or properties you wanted. It's confusing what you really want. So instead, here's an example showing how you can do what it appears you want to do:
XDocument doc = ...;
var batchClasses = doc.Descendants("node02")
.Select(n => new
{
BatchClassName = (string)n.Attribute("name") ?? "",
CustomPropertyNames = n.Descendants("CustomProperty")
.Select(cp => (string)cp.Attribute("Name") ?? "")
.ToList(),
// Here's an example to select "EMAIL" custom property names
EmailPropertyNames = n.Descendants("CustomProperty")
.Select(cp => (string)cp.Attribute("Name") ?? "") // select the names...
.Where(s => s.StartsWith("EMAIL")) // that start with "EMAIL"
.ToList(),
});
Upvotes: 1