通过innertext选择节点列表。发出XmlDocument

时间:2014-01-02 12:38:17

标签: c# xmldocument

我有以下Xml

<Main>
         <Order Id="1262">
            <Product>
               <Name>Prod1</Name>
                   <Barcode>1234</Barcode>
                </Product>
                 <Product>
                   <Name>Prod1</Name>
                   <Barcode>1234</Barcode>
                </Product>
                <Product>
                     <Name>Prod2</Name>
                   <Barcode>2345</Barcode>
               </Product>

            </Order>

        <Order Id="1263">
               <Product>
               <Name>Prod1</Name>
                   <Barcode>1234</Barcode>
                </Product>
                 <Product>
                   <Name>Prod1</Name>
                   <Barcode>1234</Barcode>
                </Product>
                <Product>
                     <Name>Prod2</Name>
                   <Barcode>2345</Barcode>
               </Product>
                </Order>
</Main>


XmlDocument xml=new XmlDocument();
xml.Load(path);

现在我想从orderId=1263的节点中仅选择条形码为1234的节点。我的代码是

 string OrderId="1262"
   string ReadedBarcode ="1234"

    XmlNode ONode = xml.SelectSingleNode("//Order[@Id='" + OrderId + "']");
     XmlNodeList BarCodeNodeList = ONode.SelectNodes("//Product/Barcode[text()='" + ReadedBarcode + "']");

但我不知道为什么来自具有innertext 1234的文档中的所有节点都被选中。这意味着甚至来自<Order Id="1263">此节点的节点也会被选中。

任何解决方案?

2 个答案:

答案 0 :(得分:3)

这应该这样做

        XmlDocument xml=new XmlDocument();
        xml.Load(path);
        string OrderId = "1262";
        string ReadedBarcode = "1234";

        XmlNodeList BarCodeNodeList = xml.SelectNodes("//Order[@Id='" + OrderId + "']"+"//Product/Barcode[text()='" + ReadedBarcode + "']");

此外,您的XML无效,缺少一些开始标记,它应该是

<Main>
  <Order Id="1262">
    <Product>
    <Name>Prod1</Name>
    <Barcode>1234</Barcode>
    </Product>
    <Product>
      <Name>Prod1</Name>
      <Barcode>1234</Barcode>
    </Product>
    <Product>
      <Name>Prod2</Name>
      <Barcode>2345</Barcode>
    </Product>

  </Order>

  <Order Id="1263">
    <Product>
    <Name>Prod1</Name>
    <Barcode>1234</Barcode>
    </Product>
    <Product>
      <Name>Prod1</Name>
      <Barcode>1234</Barcode>
    </Product>
    <Product>
      <Name>Prod2</Name>
      <Barcode>2345</Barcode>
    </Product>
  </Order>
</Main>

答案 1 :(得分:1)

我知道你写过你被XmlDocument'卡住了',但你给出的理由听起来像是一个不是基于技术限制的决定,而是基于偏好。我相信一个工具换工作,所以请原谅我写一个你可能不喜欢的解决方案,但它可能会说服你在看到好处时使用XDocument的优点。

您发布的XML在语法上不正确,下面的示例显示了我添加了缺少的产品启动器节点的更正。

以下是我建议使用LinqPad编写的代码。 Dump()方法只是将变量吐出到控制台。另外,我不知道你想找哪个“节点”,所以我在这个样本中返回Order节点。

干杯,亚伦

var doc = XDocument.Parse(@"
<Main>
    <Order Id=""1262"">
        <Product>
            <Name>Prod1</Name>
            <Barcode>1234</Barcode>
        </Product>
        <Product>
            <Name>Prod1</Name>
            <Barcode>1234</Barcode>
        </Product>
        <Product>
            <Name>Prod2</Name>
            <Barcode>2345</Barcode>
        </Product>
    </Order>
    <Order Id=""1263"">
        <Product>
            <Name>Prod1</Name>
            <Barcode>1234</Barcode>
        </Product>
        <Product>
            <Name>Prod1</Name>
            <Barcode>1234</Barcode>
        </Product>
        <Product>
            <Name>Prod2</Name>
            <Barcode>2345</Barcode>
        </Product>
    </Order>
</Main>
");

var barcode = "1234";
var orderId = "1263";
var found = (
    from row in doc.Root.Descendants("Order")
    where 
      row.Attribute("Id") != null && 
      row.Attribute("Id").Value == orderId && 
      row.Descendants("Barcode").Any(a => a.Value == barcode)
    select row).ToList();

found.Dump();