【问题标题】:Parsing XmlDocument with Variable Parent Tags使用可变父标记解析 XmlDocument
【发布时间】:2012-05-14 15:29:38
【问题描述】:

假设我有一个这样的 XmlDocument:

<xmlFile>
  <details>
    <code1>ADJ</code1>
    <code2>ADC </code2>
    <Shipment>
      <foo></foo>
      <bar></bar>
    </Shipment>
    <Shipment>
      <foo></foo>
      <bar></bar>
    </Shipment>
  </details>
  <details>
    <code1>ADJ</code1>
    <code2>SCC </code2>
    <Shipment>
      <foo></foo>
      <bar></bar>
    </Shipment>
  </details>
</xmlFile>

我需要在一个 xml 文件中处理每个,但只处理属于具有值为“ADC”的子节点的标签下的货件。到目前为止,我有:

// Assume there is an XmlDocument named xml 
XmlNodeList details= xml.GetElementsByTagName("details");

foreach (XmlNode node in details)
{
   if (node["code2"].InnerText == "ADC ")
   {
   // Get each shipment and process it accordingly.
   }
}

我不知道下一步该做什么。谢谢。

【问题讨论】:

  • “Under”=“在文本之下”还是“一个孩子”? (&lt;codeX&gt; 没有一个有意义的孩子。)
  • 你能用 XDocument 和 LINQ 代替吗?
  • 您将如何使用 LINQ 和 XDocument 实现它?现有代码库使用所有 XmlDocument。
  • 第一个细节的代码2是“ADC”而不是“ADC”,所以它不会匹配。

标签: c# .net xmldocument


【解决方案1】:

假设 Data\Sample.xml 包含问题中提到的 xml,
以下是 XLINQ 查询

    XElement root = XElement.Parse(File.ReadAllText(@"Data\Sample.xml"));
    var adcShipment = root.Descendants().Where(e=>String.Equals(e.Value, "ADC "));
    //next query for nodes/elements inside/next to ADC shipments

【讨论】:

    【解决方案2】:

    XPath 可以简化您的匹配搜索:

    foreach (XmlNode node in xml.SelectNodes("/xmlFile/details[normalize-space(code2)='ADC']"))
    {
        string foo = node.SelectSingleNode("foo").InnerText;
        string bar = node.SelectSingleNode("bar").InnerText;
    }
    

    【讨论】:

      【解决方案3】:

      我正在向这个库添加 XPath 解析:https://github.com/ChuckSavage/XmlLib/

      我修改了它,所以你可以这样做:

      XElement root = XElement.Load(file);
      var shipments = root.XPath("details[starts-with(*,'ADC')]/Shipment");
      

      长手看起来像:

      var shipments = root.Elements("details")
                          .Where(x => x.Elements().Any(xx => ((string)xx).StartsWith("ADC")))
                          .Elements("Shipment");
      

      【讨论】:

        【解决方案4】:

        这就是你所追求的东西

                XmlNodeList details = xml.GetElementsByTagName("details");
        
                foreach (XmlNode node in details)
                {
                    if (node["code2"].InnerText.Trim() == "ADC")
                    {
                        // Get each shipment and process it accordingly.
                        foreach(XmlNode shipment in node.SelectNodes("Shipment"))
                        {
                            var foo = shipment.SelectSingleNode("foo");
                            var bar = shipment.SelectSingleNode("bar");
                        }
                    }
                }
        

        【讨论】:

        • 由于某种原因,当我运行 foreach 循环时,它没有抓取 XmlNode 货件。关于为什么它没有看到任何想法?
        • @ShawnH。 Chuck 的观察是正确的,您的 XML 元素值以空格字符结尾。我已修改代码以忽略此尾随空格字符。现在对你有用吗?
        • 这是我输入问题时的错。 XML 应该有那个空间。我会调整问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-06
        • 1970-01-01
        • 1970-01-01
        • 2017-11-27
        相关资源
        最近更新 更多