根据节点在xml文档中的位置查找元素的值

时间:2016-04-27 13:21:00

标签: c# xml xml-parsing

<OverallReport>
    <Results>
       <Data1>
            <a>-30 </a>
            <b>400</b>
       </Data1>
       <Data2>
            <MoreData>
                    <c>2</c>
                    <d>100</d>
           </MoreData>
           <MoreData>
                    <c>4</c>
                    <d>200</d>
           </MoreData>
       </Data2>
   </Results>
   <Results>
       <Data1>
            <a>-50</a>
            <b>600</b>
       </Data1>
       <Data2>
           <MoreData>
                    <c>2</c>
                    <d>200</d>
           </MoreData>
           <MoreData>
                    <c>6</c>
                    <d>500</d>
           </MoreData>
      </Data2>
   </Results>
   <Results>
       <Data1>
            <a>-50</a>
            <b>600</b>
       </Data1>
       <Data2>
           <MoreData>
                    <c>2</c>
                    <d>300</d>
           </MoreData>
           <MoreData>
                    <c>6</c>
                    <d>900</d>
           </MoreData>
      </Data2>
   </Results>
</OverallReport>

我有一个XML文档,如上所述,它包含任意数量的Results节点和任意数量的MoreData节点。我必须找到包含两个特定值的结果节点(例如a = -50,b = 600),并且在该节点内,如果'c'等于特定值,则找到'd'的值。同样,有各种结果节点可能具有相同的a,b和c,我将需要找到&#39; x&#39;一。因此,如果(a = -50,b = 600,c = 6,x = 0),则寻找的d I&#39; m的值是500。如果(a = -50,b = 600,c = 6,x = 1),则寻找的d I&#39; m的值为900。

我发布了一个相关的问题,有一个有效的答案,但这有点高级,所以我决定创建一个新问题。我目前正在寻找的方式:

string wantedA = "-50";
string wantedB = "600";
string wantedC = "6";
string x=1;

string xpath = string.Format("OverallReport/Results[Data1/a={0} and Data1/b={1}]/Data2/MoreData[c={2}]/d",
wantedA, wantedB, wantedC);

XmlNode nodeD = document.SelectSingleNode(xpath);
Console.WriteLine(nodeD.InnerText);

同样,我是Xml的新手,非常感谢任何帮助或提示!

2 个答案:

答案 0 :(得分:1)

首先,你的xml中有一些错误,应该是:

<OverallReport>
    <Results>
       <Data1>
            <a>-30 </a>
            <b>400</b>
       </Data1>
       <Data2>
            <MoreData>
                    <c>2</c>
                    <d>100</d>
           </MoreData>
           <MoreData>
                    <c>4</c>
                    <d>200</d>
           </MoreData>
       </Data2>
   </Results>
   <Results>
       <Data1>
            <a>-50</a>
            <b>600</b>
       </Data1>
       <Data2>
           <MoreData>
                    <c>2</c>
                    <d>200</d>
           </MoreData>
           <MoreData>
                    <c>6</c>
                    <d>500</d>
           </MoreData>
      </Data2>    // was <Data2> - slash added
   </Results>
   <Results>
       <Data1>
            <a>-50</a>
            <b>600</b>
       </Data1>
       <Data2>
           <MoreData>
                    <c>2</c>
                    <d>300</d>
           </MoreData>
           <MoreData>
                    <c>6</c>
                    <d>900</d>
           </MoreData>
      </Data2>    // was <Data2> - slash added
   </Results>
</OverallReport>

其次,您必须将x的类型从string更改为int

string wantedA = "-50";
string wantedB = "600";
string wantedC = "6";
int x = 1; // or 0

最后,您应找到符合条件的所有节点,然后选择一个取决于x的节点:

XmlNodeList nodes = doc.SelectNodes(xpath);            
Console.WriteLine(nodes[x].InnerText);

所以,你的代码应该是:

    string wantedA = "-50";
    string wantedB = "600";
    string wantedC = "6";
    int x = 1; // or 0

    string xpath = string.Format("OverallReport/Results[Data1/a={0} and Data1/b={1}]/Data2/MoreData[c={2}]/d",
    wantedA, wantedB, wantedC);

    XmlNodeList nodes = doc.SelectNodes(xpath);            
    Console.WriteLine(nodes[x].InnerText);

答案 1 :(得分:1)

将整个XPath包装在parens中并应用位置索引过滤器/谓词,例如:

(OverallReport/Results[Data1/a=-50 and Data1/b=600]/Data2/MoreData[c=6]/d)[2]

请注意,XPath索引从1开始,而不是像C#中的0。因此,上面的XPath表达式将返回900给出的样本XML作为测试文档。