简体   繁体   中英

Reading XML in C#

I have the following xml

<Objects>
    <Object>
        <ViewAngle>90</ViewAngle>
        <ViewMode>ThirdPerson</ViewMode>
        <Top>50</Top>
        <Left>100</Left>
    </Object>
</Objects>

I have the following code to read this xml

           XmlDataDocument doc = new XmlDataDocument();
           doc.Load(xmlPath);
           XmlElement root = doc.DocumentElement;
           XmlNodeList nodes = root.SelectNodes("/Objects/Object");
           foreach (XmlNode node in nodes)
           {
                if (node.InnerXml.Contains("View"))
                {
                  string viewType=node["View"].InnerText;
                  //..... other stuffs
                }
                if (node.InnerXml.Contains("ViewAngle"))
                {
                  string viewAngle=node["ViewAngle"].InnerText;
                  //..... other stuffs
                }
                if (node.InnerXml.Contains("ViewMode"))
                {
                  string viewMode=node["ViewMode"].InnerText;
                  //..... other stuffs
                }
           }

Above code is working fine if my xml contains one more tag ie <View>3dView</View> . But if it does not contains the View tag, then it produces error.

The InnerXml.Contains() is a simple string method that checks for the sub-string is present in the string or not.

In my case the Contains("View") returns true as View is present in ViewAngle and in ViewMode that is why it is going inside the if block of View but when it tries to read the node["View"] , it produces error as View node is not exists in the xml.

How to resolve this error?

You are missing the fact that XML is structured data, not string. This is completely the wrong approach:

if (node.InnerXml.Contains("View")) {
  // ...
}

You want this:

XmlNode child = node.SelectSingleNode("./View");
if (child != null) {
  // now do something with 'child' ...
}

Try this loop instead:

        foreach (XmlNode node in nodes) {
            foreach (XmlNode prop in node.ChildNodes) {
                if (prop.NodeType != XmlNodeType.Element)
                    continue;

                switch (prop.Name) {
                    case "View":
                        string viewType = prop.InnerText;
                        // ...
                        break;

                    case "ViewAngle":
                        string viewAngle = prop.InnerText;
                        // ...
                        break;

                    case "ViewMode":
                        string viewMode = prop.InnerText;
                        // ...
                        break;
                }
            }
        }

If the View element is not present, it cannot be found. You can use the GetElementsByTagName("View") method instead. This will return null if the view element is not there.

You can make some modifications in this function and use it acordingly

 XDocument xDoc=XDocument.Load(@"C:\File.xml");            
Process(xDoc.Root);


public static void Process(XElement element)
        {
            if (element.HasElements)
            {
                Console.WriteLine("<" + element.Name.LocalName + ">");
                foreach (XElement child in element.Elements())
                {
                    Process(child);
                }
                Console.WriteLine("<" + element.Name.LocalName + ">");
            }
            else
            {
                Console.WriteLine("<" + element.Name.LocalName);
                if(element.HasAttributes)
                {
                    foreach (XAttribute attr in element.Attributes())
                    {
                        Console.WriteLine(attr.Name +"="+attr.Value);
                    }
                }
                Console.WriteLine(">" + element.Value + "</" + element.Name.LocalName + ">");  
            }
        }

if trageting 3.5 or above u can use linq

XDocument XDoc = XDocument.Load(@"C:\UrXMLFile.xml");


var q = from b in xml.Descendants("product")
        select new
        {
            View      = (string)b.Element("View") ?? "3dView",
            ViewAngle = (double?)b.Element("ViewAngle") ?? 90.0,                    
            ViewMode  = (string)b.Element("ViewMode") ?? ThirdPerson,
            Top       = (double?)b.Element("Top") ?? 0.0,
            Left      = (double?)b.Element("Left") ?? 0.0
        };

So if View is not found it have a default value always. Also u can create ur class object in select new. Note: I have not compiled it.

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