Search code examples
c#xpathxmlnodexmlnodelist

XMLNodeList/XPath - looping, but getting same first node over and over


What have I forgetten? Seems like I've done this before with no issues. As I loop through the XmlNodeList, I want to get the values of each node, but I seem to be getting the first node over and over.

string strXpathHL1Loop = "//*[local-name()='HLLoop1']";
XmlNodeList nodeList = xmlDoc856.SelectNodes(strXpathHL1Loop);
Console.WriteLine("Number HLLoop1 nodes=" + nodeList.Count);  

int lineNum = 0;
int loopNum = 0; 

foreach (XmlNode node in nodeList)
{
    loopNum++; 
    Console.WriteLine("\n-----LoopNum=" + loopNum);
    Console.WriteLine(node.OuterXml);   
    string xpathHL01 = "//HL01";
    XmlNode HL01Node = node.SelectSingleNode(xpathHL01);
    Console.WriteLine("HL01Node.OuterXml=" + HL01Node.OuterXml); 
    Console.WriteLine("HL01=" + HL01Node.InnerText);

    string xpathHl03 = "//HL03"; 
    XmlNode Hl03Node = node.SelectSingleNode(xpathHl03);
    Console.WriteLine("HL03Node.OuterXml=" + Hl03Node.OuterXml);
    Console.WriteLine("HL03=" + Hl03Node.InnerText); 
}


-----LoopNum=1
<ns0:HLLoop1 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"><ns0:
HL><HL01>1</HL01><HL02 /><HL03>S</HL03></ns0:HL><ns0:TD5><TD501>B</TD501><TD505>
UNSP_CG</TD505></ns0:TD5><ns0:DTM_2><DTM01>011</DTM01><DTM02>20190425</DTM02></n
s0:DTM_2></ns0:HLLoop1>
HL01Node.OuterXml=<HL01>1</HL01>
HL01=1
HL03Node.OuterXml=<HL03>S</HL03>
HL03=S

-----LoopNum=2
<ns0:HLLoop1 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"><ns0:
HL><HL01>2</HL01><HL02>1</HL02><HL03>O</HL03></ns0:HL><ns0:PRF><PRF01>287775</PR
F01></ns0:PRF></ns0:HLLoop1>
HL01Node.OuterXml=<HL01>1</HL01>
HL01=1
HL03Node.OuterXml=<HL03>S</HL03>
HL03=S

Expected result of loop 2:

HL01=2
HL03Node.OuterXml=<HL03>O</HL03>
HL03=O

Here's the minimal data to reproduce:

<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
    <ns0:HLLoop1>
        <ns0:HL>
            <HL01>1</HL01>
            <HL02/>
            <HL03>S</HL03>
        </ns0:HL>
    </ns0:HLLoop1>
    <ns0:HLLoop1>
        <ns0:HL>
            <HL01>2</HL01>
            <HL02>1</HL02>
            <HL03>O</HL03>
        </ns0:HL>
    </ns0:HLLoop1>
</ns0:X12_00401_856>

Solution

  • Use a path going downwards relative to the node context node so e.g.

    string xpathHL01 = ".//HL01";
    

    or

    string xpathHL01 = "descendant::HL01";
    

    Your attempts starting with / start searching/selecting from the root node/document node of the context node so you end up with same node with each selection.