简体   繁体   中英

Robust Parsing xml using XmlDocument in c#

I have the following code

XmlDocument doc = new XmlDocument();
doc.Load(xmlFileName);

XmlNode deeperNodes = 
        doc.DocumentElement.ChildNodes[11].ChildNodes[1].ChildNodes[3].ChildNodes[1].ChildNodes[2];
XmlNode deeperetNodes = 
        doc.DocumentElement.ChildNodes[11].ChildNodes[1].ChildNodes[3].ChildNodes[1].ChildNodes[3];

string firstValue = deeperNodes.Attributes["count"].Value.ToString();
string secondValue = deeperetNodes.Attributes["count"].Value.ToString();

The XML I am reading is to a given standard so is always the correct. Is there a better more robust way to read the values?

Update: Sample Xml

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Rn>
    <Te>Fort</Te>
    <Th></Th>
    <Lh>c</Lh>
    <Fe>C</Fe>
    <Ue></Ue>
    <RS></RS>
    <RS></RS>
    <RS></RS>
    <RS> </RS>
    <RS></RS>
    <RS></RS>
    <RS>
        <Tl>New</Tl>
        <SS>
            <Tl>New</Tl>
            <Description>A</Description>
            <Text>The</Text>
            <IssueListing>
                <Refinement></Refinement>
                <Chart ce="p">
                    <Axis>New</Axis>
                    <MajorAttribute>Anal</MajorAttribute>
                    <GroupingSection count="38">
                        <groupTl>Is</groupTl>
                    </GroupingSection>
                    <GroupingSection count="364">
                        <groupTl>Is</groupTl>
                    </GroupingSection>
                </Chart>
            </IssueListing>
        </SS>
    </RS>
</Rn>

Here's some ideas on more robust parsing, using XPath. The idea here is to latch onto an element of interest, which I've taken to be the Chart element with attribute ce with a value of 'p', and then use this as a frame of reference. Also, unless the Xml has been validated (eg vs an XSD), don't assume that elements exist or are valid, so check for nulls, invalid data types, etc.

XmlDocument with XPath version :

var doc = new XmlDocument();
doc.LoadXml(xmlFileName);

int firstValue, secondValue;
var interestingChartNode = doc.SelectSingleNode("//Chart[@ce='p']");
if (interestingChartNode != null)
{
    firstValue = Convert.ToInt32(interestingChartNode
                                 .SelectSingleNode("GroupingSection[1]/@count").Value);
    secondValue = Convert.ToInt32(interestingChartNode
                                 .SelectSingleNode("GroupingSection[2]/@count").Value);
}

Alternatively, Linq to Xml
(Personally I would still skip over all the ignored nodes with XPath, but others may disagree):

var xdoc = XDocument.Parse(xmlFileName); // using System.Xml.Linq;
var interestingGroupingSections = xdoc
         .XPathSelectElements("//Chart[@ce='p']/GroupingSection"); // using System.Xml.XPath;
if (interestingGroupingSections.Any())
{
    firstValue = Convert.ToInt32(interestingGroupingSections.First()
       .Attributes("count")
       .First().Value);
    secondValue = Convert.ToInt32(interestingGroupingSections.Skip(1)
       .Attributes("count")
       .First().Value);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM