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 i.e. <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.
精彩评论