clx
clx

Reputation: 824

Getting all the attributs of a subelement

I have problems getting the Attributes of a XmlSchema sub element.

There is an abstactElement and a concreteElement which extends the abstractElement. Getting the base's attributes works fine using XmlSchemaComplexType.BaseXmlSchemaType. But getting the concreteElement's attributes using XmlSchemaComplexType.Attributes does not work.

This is my example Xml-Schema file:

<xs:schema id="XMLSchema1"
    targetNamespace="http://tempuri.org/XMLSchema1.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
    <xs:element name = "ConcreteElement" type="concreteElement" />

    <xs:complexType name="abstractElement">
        <xs:attribute name="aA1" type="xs:string" />
        <xs:attribute name="aA2" type="xs:string" />
        <xs:attribute name="aA3" type="xs:string" />    
    </xs:complexType>

    <xs:complexType name="concreteElement">
        <xs:complexContent>
            <xs:extension base="abstractElement">
                <xs:attribute name="cA1" type="xs:string"/>
                <xs:attribute name="cA2" type="xs:string"/>
                <xs:attribute name="cA3" type="xs:string"/>
            </xs:extension>    
        </xs:complexContent>
    </xs:complexType>
</xs:schema>

I want to get all attributes of the ConcreteElement (cA1, cA2, cA3) and all the attributes of its base element (aA1, aA2, aA3).

My code looks like that:

public Program()
{
    XmlSchema xsd =
          XmlSchema.Read(
              new StreamReader("/Path/To/My/Xsd/File.xsd"),
              null);

    var xss = new XmlSchemaSet();
    xss.Add(xsd);
    xss.Compile();

    XmlSchemaElement xsdRoot = null;
    /* Get the root element */
    foreach (DictionaryEntry curEle in xsd.Elements)
    {
        var xse = (XmlSchemaElement)curEle.Value;
        xsdRoot = xse;
        break;
    }

    List<XmlSchemaAttribute> lsAttributes = this.GetAllAttributes(
                          xsdRoot.ElementSchemaType as XmlSchemaComplexType);
    foreach (XmlSchemaAttribute curAtr in lsAttributes)
    {
        Console.WriteLine(curAtr.Name);
    }

    Console.ReadKey();
}

And this is my GetAllAttributes method:

private List<XmlSchemaAttribute> GetAllAttributes(
    XmlSchemaComplexType comCon)
{
    /* No Ancestor, no Attributes */
    if (comCon == null)
    {
        return new List<XmlSchemaAttribute>();
    }

    /* Get attributs of the acestors */
    List<XmlSchemaAttribute> allAttributes =
        this.GetAllAttributes(
            comCon.BaseXmlSchemaType as XmlSchemaComplexType);

    /* Ad the attributes of the given element */
    allAttributes.AddRange(comCon.Attributes.Cast<XmlSchemaAttribute>());

    return allAttributes;
} 

Regards,

Upvotes: 3

Views: 2017

Answers (1)

clx
clx

Reputation: 824

Finally the solution is to use the Property AttributeUses, which holds all the attributes of an element, even those which belong to the ancestors.

private List<XmlSchemaAttribute> GetAllAttributes(
    XmlSchemaComplexType comCon)
{        
    List<XmlSchemaAttribute> allAttributes = new List<XmlSchemaAttribute>();

    /* Add the attributes of the given element */
    foreach (DictionaryEntry curAttriEntry in comCon.AttributeUses)
    {
        XmlSchemaAttribute curAttri =
            curAttriEntry.Value as XmlSchemaAttribute;

        if (curAttri != null)
        {
            allAttributes.Add(curAttri);
        }
    }

    return allAttributes;
}

Upvotes: 2

Related Questions