简体   繁体   English

使用子节点解析 XML

[英]Parse XML with Child Nodes

I have an XML file which returns a list of products with colors and inventory for each color.我有一个 XML 文件,它返回带有颜色和每种颜色库存的产品列表。 What is the best method to loop through this data only returning inventory by color for a specific product ie PL-0223?循环遍历此数据的最佳方法是仅按颜色返回特定产品(即 PL-0223)的库存?

Here is the data.这是数据。

<Part fpartno="0019">
    <Color colorname="Nickel"> 
        <ValueAmt>
            <Values Qty= "12101" Date ="ATP" Type= "Avail"/>
            <Values Qty= "12101" Date= "Total" Type="Total"/> 
        </ValueAmt>
    </Color>
</Part>
<Part fpartno="0223">
    <Color colorname="White"> 
        <ValueAmt>
            <Values Qty= "0" Date ="ATP" Type= "Avail"/>
            <Values Qty= "0" Date= "Total" Type="Total"/> 
        </ValueAmt>
    </Color>
    <Color colorname="Yellow"> 
        <ValueAmt>
            <Values Qty= "0" Date ="ATP" Type= "Avail"/>
            <Values Qty= "0" Date= "Total" Type="Total"/> 
        </ValueAmt>
    </Color>
</Part>

I've seen examples using both Linq to SQL and XmlReader but I have not found a good solution to loop through SubTree's/Child Nodes.我已经看到使用 Linq to SQL 和 XmlReader 的示例,但我还没有找到一个很好的解决方案来循环遍历子树/子节点。

Examples of what I've tried.我尝试过的例子。

XmlReader Method. XmlReader 方法。 I can't seem to figure out how to get the sub elements.我似乎无法弄清楚如何获取子元素。

using(XmlReader r = XmlReader.Create(URLString))
{
    while(r.Read())
    {
        if((r.NodeType == XmlNodeType.Element) && (r.Name == "Part"))
        {
            if(r.HasAttributes)
            {                    
                if(r.GetAttribute("fpartno") == "0019")
                {
                    using (XmlReader cr = r.ReadSubtree())
                    {
                        Console.WriteLine(cr.Name)
                    }
                }
            }
        }
    }
}

I've also tried XDoc我也试过 XDoc

XDocument xdoc = XDocument.Load(URLString);
foreach (XElement element in xdoc.Descendants("Values"))
{
    Console.WriteLine(element);
} 

But can't seem to figure out how to only get colors for "0019".但似乎无法弄清楚如何只为“0019”获取颜色。

You can try:你可以试试:

var part = xdoc.Descendants("Parts")
             .FirstOrDefault(x => (string)x.Attribute("fpartno") == "0223");

if(part != null)
{
   var values = part.Descendants("Values");
}

This is the Raison d'être of XPath:这是 XPath 存在的理由:

var doc = new System.Xml.XmlDocument();
doc.Load(URLString);

foreach(System.Xml.XmlNode node in 
   doc.SelectNodes("//Part[@fpartno='0223']/Color[@colorname='White']/ValueAmt/Values")
{
  Console.WriteLine(node.InnerXml);
}

Note that your sample data above is not a valid XML document - it's an Xml fragment.请注意,您上面的示例数据不是有效的 XML 文档 - 它是一个 Xml 片段。 To use XPath on it, you'll need to wrap the data in a root node so that the resulting document has a single root (unless it already has a wrapper that you just didn't show).要在其上使用 XPath,您需要将数据包装在一个根节点中,以便生成的文档只有一个根(除非它已经有一个您没有显示的包装器)。 Working out the general case of how to construct the XPath query string is left as an exercise for the student.解决如何构造 XPath 查询字符串的一般情况留给学生作为练习。

Also note that XDocument doesn't support XPath - only the pre-LINQ XmlDocument class support XPath directly.另请注意,XDocument 不支持 XPath - 只有 LINQ 之前的 XmlDocument 类直接支持 XPath。 You can mix XPath and XDocument, however, by using XDocument.CreateNavigator to create an XPathNavigator, which you can then query using XPath.但是,您可以混合使用 XPath 和 XDocument,方法是使用 XDocument.CreateNavigator 创建一个 XPathNavigator,然后您可以使用 XPath 进行查询。

Here's the solution I came up with.这是我想出的解决方案。

string URLString = "http://example.com/test.xml";
XElement xelement = XElement.Load(URLString);
var part = from partno in xelement.Descendants("Part")
           where (string)partno.Attribute("fpartno") == "0019"
           select partno;

foreach (XElement xEle in part)
{
    Console.log(xEle.Element("Color").Attribute("colorname").Value);

    foreach (var node in xEle.Element("Color").Element("ValueAmt").Elements("Values"))
    {
        Console.log(node.Attribute("Qty").Value);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM