views:

317

answers:

3

I am trying to use XmlReader to parse a file and set each element's attributes to variables using reader.GetAttribute("atrribute_name"), but the elements may or may not actually have that attribute present, so some elements give me an error...I would have expected it would just return null when the attribute is not present, but instead it throws errors.

Here's the full exception:

System.Xml.Schema.XmlSchemaException: The 'opacity' attribute is not declared.
   at System.Xml.XmlValidatingReaderImpl.InternalValidationCallback(Object sender, ValidationEventArgs e)
   at System.Xml.Schema.BaseValidator.SendValidationEvent(XmlSchemaException e, XmlSeverityType severity)
   at System.Xml.Schema.BaseValidator.SendValidationEvent(XmlSchemaException e)
   at System.Xml.Schema.DtdValidator.ValidateStartElement()
   at System.Xml.Schema.DtdValidator.ProcessElement()
   at System.Xml.Schema.DtdValidator.ValidateElement()
   at System.Xml.Schema.DtdValidator.Validate()
   at System.Xml.XmlValidatingReaderImpl.ProcessCoreReaderEvent()
   at System.Xml.XmlValidatingReaderImpl.Read()
   at Squared.Tiled.Map.Load(String filename, ContentManager content) in C:\Users\Stephen\Documents\Visual Studio 2008\Projects\Tiled\Tiled.cs:line 650

and here's the xml content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map SYSTEM "http://mapeditor.org/dtd/1.0/map.dtd"&gt;
<map version="1.0" orientation="orthogonal" width="32" height="32" tilewidth="32" tileheight="32">
 <tileset name="Untitled" firstgid="1" tilewidth="32" tileheight="32">
  <image source="tiles.png"/>
 </tileset>
<layer name="" width="32" height="32" opacity="0.72">
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAAO3DAQkAAAwEofv+pddjKLhqqqqq6usHHB1pSAAQAAA=
  </data>
 </layer>
 <layer name="Layer 1" width="32" height="32">
  <properties>
   <property name="layermeta" value="layervalue"/>
  </properties>
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAAO2UUQrAMAhD+7P7X3nsbwydibrJRh6UQloatbZrzbMZI9KZc5g4EB3dx9Lhn8m707+C5cP2ReX+p7ByuK55WlQz1P9u9vZFOkrVJ6pXxR/pM/TcjD+in9e/1vsHXtzV/Cfqn+GJ+2f9u+qfgX3Pf/v/hRBCiLfZAUDgXx4AEAAA
  </data>
 </layer>
</map>

opacity may or may not be present in each layer, along with several other attributes.

+1  A: 

Yes. Read the documentation for XmlReader. You'll find it has many methods and properties.

In particular, you'll find the Item property, the HasAttributes property, and the AttributeCount property.

John Saunders
None of that helps. If I have one element that is <element attribute1="something" /> and I have another that is <element attribute2="something" /> the reader will have the same Attribute Count. What I need is some way to check if that specific attribute is present, not how many are present.
Stephen Belanger
for (i=0;i<reader.AttributeCount;i++) {process reader[i].Name, reader[i].Value;}
John Saunders
A: 

Are you sure that where you have "attribute_name" in your example you are always passing a valid string? Seems to me that your error could be because you're passing null to GetAttribute.

Jeff Yates
That's not it. The attribute collecting code is passed over several times, as there is several of the same element. The first few times it passes over fine because all the attributes I'm trying to assign to variables are present. But then it throws and error when it gets to one of them that doesn't have that attribute. I can't use AttributeCount because there is several attributes and all of them are optional, so it can't be predicted.
Stephen Belanger
A: 

Apparently the issue wasn't xml related at all; the GetAttribute() calls on attributes that weren't present were returning null...but it was passing into float.Parse(), which doesn't work. The compiler kept telling me it was XmlSchema related, so I was looking in the wrong places. >.>

That bug was such a pain to debug.

Stephen Belanger
Yeah, but that doesn't solve your XmlSchemaException problem, does it?
John Saunders
Yes, it does actually--all I did was this, and it worked: string tempopacity = reader.GetAttribute("opacity"); if (tempopacity != null) { result.Opacity = float.Parse(tempopacity); }
Stephen Belanger