Sean P
Sean P

Reputation: 949

Adding a custom/dynamic attribute when using XSD.exe

I am using xsd.exe to generate a C# class that will be used to serialize data to XML. However one of the attributes that I have for a tag is dynamic.

ex:

<foo cat="onething">
or
<foo dog="something">

Is there any way to do this?

Upvotes: 1

Views: 1806

Answers (1)

gitsitgo
gitsitgo

Reputation: 6769

As far as I know, the only way to make attribute names dynamic is to account for any attribute. After you create your XML Schema, add an <xs:anyAttribute> attribute in the XSD file and then generate your class.

<xs:element maxOccurs="unbounded" name="Project">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Name" type="xs:string" />
      <xs:element name="Mark">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:unsignedByte">
              <xs:attribute name="IsLate" type="xs:string" use="optional" />
              <xs:attribute name="MadeEarlyDeadline" type="xs:string" use="optional" />
              <xs:anyAttribute/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>

Your xml object class will have an `XmlAttribute[] AnyAttr' property. Any new attribute that isn't defined in the XML object will appear in this property when you deserialize, but when you serialize, it will appear as a new attribute.

Serialization Example... let's say the person 'cheated' in the project.

        xmlProject project = new xmlProject();

        XmlDocument xd = new XmlDocument();
        XmlAttribute cheated = xd.CreateAttribute("Cheated");
        cheated.Value = "Yes";

        XmlAttribute[] xa = new XmlAttribute[]{ cheated };

        project.Mark = new xmlProjectMark() { IsLate = "Yes", MadeEarlyDeadline = "False", AnyAttr = xa, Value=70 };
        project.Name = "Jonathan";

        XmlSerializer writer = new XmlSerializer(typeof(xmlProject));

        StreamWriter file = new StreamWriter(@"C:\test.xml");
        writer.Serialize(file, project);
        file.Close();

The above will give you something like this:

<xmlProject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Jonathan</Name>
  <Mark IsLate="Yes" MadeEarlyDeadline="False" Cheated="Yes">70</Mark>
</xmlProject>

And to deserialize:

        XmlDocument xd2 = new XmlDocument();
        xd2.Load(@"C:\test.xml");
        XmlSerializer xs = new XmlSerializer(typeof(xmlProject));
        xmlProject deserializedProject = (xmlProject)xs.Deserialize(new XmlNodeReader(xd2.DocumentElement));

Sorry for the long answer, hope it solves your requirements... :)

Upvotes: 3

Related Questions