C# 按innertext选择节点列表。发布XML文档

C# 按innertext选择节点列表。发布XML文档,c#,xmldocument,C#,Xmldocument,我有以下Xml <Main> <Order Id="1262"> <Product> <Name>Prod1</Name> <Barcode>1234</Barcode> </Product> <Product>

我有以下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);
但我不知道为什么文档中包含innertext 1234的所有节点都被选中。这意味着即使来自此节点的节点也会被选中


有什么解决方案吗?

我知道您在文章中写道,您“被困”在XmlDocument上,但您给出的理由听起来似乎不是基于技术约束,而是基于偏好。我相信这项工作有一个工具,所以请原谅我写了一个你可能不喜欢的解决方案,但它可能会说服你在你看到好处的地方使用XDocument的优点

您发布的XML在语法上不正确,下面的示例显示了我添加缺少的Product starter节点的更正

下面是我的建议,用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();

我知道您曾写道,您“被困”在XmlDocument中,但您给出的理由听起来似乎不是基于技术约束,而是基于偏好。我相信这项工作有一个工具,所以请原谅我写了一个你可能不喜欢的解决方案,但它可能会说服你在你看到好处的地方使用XDocument的优点

您发布的XML在语法上不正确,下面的示例显示了我添加缺少的Product starter节点的更正

下面是我的建议,用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();
这应该可以

        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>
这应该可以

        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>

您是坚持使用XmlDocument,还是可以使用XDocument?我这样问是因为XML对XDocument的Linq查询能力使得这项任务比您在这里使用的XPath解决方案更易于表达。我完全同意您的看法,但我的项目有点大,我现在更进一步地改变了基础。而且截止日期也不太远,所以不能使用Linq到XmlDocument。您使用的是XmlDocument还是XDocument?我这样问是因为XML对XDocument的Linq查询能力使得这项任务比您在这里使用的XPath解决方案更易于表达。我完全同意您的看法,但我的项目有点大,我现在更进一步地改变了基础。而且截止日期也不太远,所以不能使用Linq To XmlWhat node you want select/output from the query?条形码、产品或订单?好的,则必须反转查询以选择Root.groundsBarcode,以便输出条形码元素。在任何情况下,@CeeTee的解决方案都能满足您的需要,并且所需的更改更少。您希望从查询中选择/输出哪个节点?条形码、产品或订单?好的,则必须反转查询以选择Root.groundsBarcode,以便输出条形码元素。在任何情况下,@CeeTee的解决方案都能满足您的需要,并且需要的更改更少。