kosh
kosh

Reputation: 561

Parsing Xsd for attributes in C#

I'm trying to parse a custom XSD to build a list of elements which have custom attributes defined. I've pasted a sample node from my XSD below. In my case, I'm trying to build a list of all elements (simple and complex types) that have been marked as static. Sample -

    <xs:element name="ATestEnum">
      <xs:annotation>
        <xs:appinfo>
          <ConfigurationMemberMetadata>
            <Static>False</Static>
          </ConfigurationMemberMetadata>
        </xs:appinfo>
      </xs:annotation>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Sample1" />
          <xs:enumeration value="Sample2" />
        </xs:restriction>
      </xs:simpleType>
    </xs:element>

I just can't figure out a way to query 'inside' an element for the properties I need. I've gotten as far as this -

var doc = XDocument.Load(schemaFileName);            
foreach (var element in doc.Descendants(xs + "element"))
{
    Console.WriteLine(element.Attribute("name").Value);
}

This gives me a list of all the elements in the xsd but not the specific property (ConfigurationMemberMetadata) that I need to check. I see the element.Annotation(type) method but how do I cast it to extract the fields I'm looking for?

I also tried using the XmlTextReader and reading the schema, compiling the schemaset and iterating through the elements but that doesn't help either.

Can someone point me in the right direction? I'm very new to xml parsing and would really appreciate your help! Thanks.

Upvotes: 3

Views: 5218

Answers (2)

Adil B
Adil B

Reputation: 16806

Make use of an Xpath query to selectively find only the nodes that you are interested in ('Static' nodes).

Here is a good example of how to do that: http://support.microsoft.com/kb/308333

If you need practice with XPath, use this "testbed" to get acquainted with its syntax: http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

Using your sample XML, this Xpath query will find all "Static" nodes:

/xml/xs:element/xs:annotation/xs:appinfo/ConfigurationMemberMetadata/Static

Upvotes: 2

Petru Gardea
Petru Gardea

Reputation: 21638

You have to use something like this:

XmlReader reader = XmlReader.Create(@"D:\....\your-file.xsd");
XDocument doc = XDocument.Load(reader);
XmlNamespaceManager ns = new XmlNamespaceManager(reader.NameTable);
ns.AddNamespace("", "http://tempuri.org/XMLSchema.xsd");
XNamespace xs = "http://www.w3.org/2001/XMLSchema";
foreach (var element in doc.Descendants(xs + "element")) { Console.WriteLine(element.Attribute("name").Value); }
foreach (XElement element in (IEnumerable)doc.XPathEvaluate("//ConfigurationMemberMetadata")) { Console.WriteLine(element.Name); }

Annotations are not showing up in the infoset, they're something else. To get to your element, use an XPath.

One thing to pay attention is the namespace you associate with your prefix. Typically, in an XSD file, the default namespace matches the target namespace, which is why I've set a dummy namespace - update to match yours. If you don't have a default namespace, just set the uri to the empty string as well.

Here is the XSD I've used with the code above:

<?xml version="1.0" encoding="utf-8" ?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="ATestEnum"> 
        <xs:annotation> 
            <xs:appinfo> 
                <ConfigurationMemberMetadata> 
                    <Static>False</Static> 
                </ConfigurationMemberMetadata> 
            </xs:appinfo> 
        </xs:annotation> 
        <xs:simpleType> 
            <xs:restriction base="xs:string"> 
                <xs:enumeration value="Sample1"/> 
                <xs:enumeration value="Sample2"/> 
            </xs:restriction> 
        </xs:simpleType> 
    </xs:element>
</xs:schema>

Upvotes: 4

Related Questions