0

I have an xml name as recipe.xml

<sections>
<section name="Template">
<item key="SkipTemplates" value="C:/Temp/skip.xm;" />
<item key="validateTemplate" value="C:/Temp/validate.xml" />
<item key="PassTemplate" value="C:/Temp/pass.xml" />
</section>
<section name="Version">
<item key="MenuTemplate" value="C:/TempVersion/menu.xml" />
<item key="PassTemplate" value="C:/TempVersion/pass.xml" />
<item key="SkipTemplate" value="C:/TempVersion/skip.xml" />
</section>
</sections>

I wish to used C# code to return me the value of each node. For example: I want to get the value(C:/Temp/validate.xml) for the node that name (validateTemplate)

I have try below code but return me error:

XmlDocument xml = new XmlDocument();
xml.Load("C:/Mani/recipe.xml");
XmlElement directoryElement = xml.GetElementById("validateTemplate");
string backupPath = directoryElement.GetAttribute("value");
MessageBox.Show(backupPath.ToString());

enter image description here

Shi Jie Tio
  • 2,479
  • 5
  • 24
  • 41
  • For GetElementById to work, it has to be known which attribute is working as ID. This can be done either by a DTD or an XSD. See the Remarks section here: [XmlDocument.GetElementById](https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmldocument.getelementbyid) – Klaus Gütter Oct 08 '20 at 05:38
  • You can also use the attribute value and get the node with either [LINQ2XML](https://learn.microsoft.com/en-us/dotnet/standard/linq/find-element-specific-attribute) or [XPath](https://stackoverflow.com/questions/6704585/get-attribute-value-from-c-xpath). Either way, you should include fortification against NullReferenceException in case no element has been found that satisfies your search term. – Fildor Oct 08 '20 at 05:57
  • @KlausGütter hi, may I get more info from you, i have no ideas by the DTD and XSD where can be set. – Shi Jie Tio Oct 08 '20 at 06:01
  • `validateTemplate` is not the name of node. It's an attribute. – Maciej Los Oct 08 '20 at 06:07
  • 3
    XPath example: `var node = xml.DocumentElement.SelectSingleNode("//item[@key = 'validateTemplate']/@value"); MessageBox.Show(node?.Value ?? "Not found"); ` – Fildor Oct 08 '20 at 06:13
  • 1
    FYI for this exception: https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it – Hans Kesting Oct 08 '20 at 06:56

1 Answers1

2

In this case it might be easiest to use an XPath expression to find the item you are looking for. You can turn this into a function that uses the name of the section and item name as parameters.

Something like this:

var templatePath = xml.DocumentElement?.SelectSingleNode("/sections/section[@name='Template']/item[@key='validateTemplate']/@value")?.Value;

or play with it an select all section.items:

foreach (XmlNode item in xml.DocumentElement.SelectNodes("/sections/section/item"))
{
    Console.WriteLine($"{item.ParentNode.Attributes["name"]?.Value}.{item.Attributes["key"]?.Value}\t{item.Attributes["value"]?.Value}");
}
Rick
  • 3,361
  • 1
  • 22
  • 29