XmlNodeList changeValues = doc.SelectNodes("//x:Textbox[contains(@Name, 'Report_')]//x:Value", xmlnsManager);
*Edit Say a section of my XML file looks like this:
<Textbox Name="Report_Banana">
<TextRun>
<Value>Banana</Value>
</TextRun>
<TextRun>
<Value>Other thing</Value>
</TextRun>
</Textbox>
<Textbox Name="Report_Apple">
<TextRun>
<Value>Apple</Value>
</TextRun>
<TextRun>
<Value>Other thing</Value>
</TextRun>
</Textbox>
I want to only add the first value in each textbox to my list. So my list would contain Banana and Apple, and not the other things.
How can I edit my Xpath to do that? The Xpath works so far, but it's still picking up the Other Thing values.
I need to use X: as I am using a namespace in the root.
I have tried:
XmlNodeList changeValues = doc.SelectNodes("//x:Textbox[contains(@Name, 'Report_')]//x:Value"[1], xmlnsManager);
But it picks up the unwanted values still.
Thanks in advance!
CodePudding user response:
Your whole XML is invalid, because the attribute values are not quoted.
So, your XML should rather be
<Textbox Name="Report_Banana">
<Value>Banana</Value>
<Value>Other thing</Value
</Textbox>
<Textbox Name="Report_Apple">
<Value>Apple</Value>
<Value>Other thing</Value
</Textbox>
And then, your XPath-1.0 could be
//Textbox[contains(@Name, 'Report_')]/Value[1]
which would select the first Value
child of the Textbox
element.
With the x:
namespace given, it could look like
//x:Textbox[contains(@Name, 'Report_')]//x:Value[1]
And a namespace agnostic version would be
//*[local-name()="Textbox" and contains(@Name, 'Report_')]/*[local-name()="Value"][1]
All three XPath expressions should result in the same nodeset; of course, depending on the context.
CodePudding user response:
Assuming you have a root element (and not multiple root Textbox as shown in OP), you could use the following to get the first Value for each TextBox
//Textbox[contains(@Name, 'Report_')]/Value[1]