开发者

Determine basic types of elements and attributes from schema

I have given the local name of an element or attribute and the schema for the document. What is the easiest way to determine the basic datatype of the element or attribute. By basic datatype I mean the xs:string, xs:date etc. (The built in data types for the xml schema.)

One of the problems I face is that it is rare for the elements type to be开发者_如何学Go one of the basic built in types. 99% of the time it is a complex type that 50% of the time refers to another complex type that refers to another complex type and so on.

A simple Example for this schema: I want to find the basic type for Employee/Person/Name/LastName (determine that LastName is xs:normalizedString). In the schema Employee is defined as an xs:element and type="bns:EmployeeType"

EmplyeeType has a Person element defined but it is type "PersonType" and then Name in person is NameType which is a complex type that extends GeneralName type that is type BasicNameType and that type finally defines the LastName which is of type "LastNameType" and on and on. There also definitions etc.

I am currently writing a parser using linq-to-xml to get at this but it isn't easy or pretty. I have searched for other solutions and haven't found any but I fully admit my XML/schema/XPath ignorance.

Is there an easy way to get the basic type for elements?


The .NET framework has a schema object model (SOM) and there are hooks to access schema types while validating with an XmlReader or after validating a System.Xml.XmlDocument or a System.Xml.Linq.XDocument. Here is a sample that show how to validate a System.Xml.Linq.XDocument and how to then access schema information:

    Dim doc As XDocument = XDocument.Load("..\..\XMLFile1.xml")
Dim schemaSet As New XmlSchemaSet()
schemaSet.Add(Nothing, "..\..\XMLFile1.xsd")

doc.Validate(schemaSet, Nothing, True)

For Each leafElement As XElement In doc.Descendants().Where(Function(d) Not (d.Elements().Any()))
    Console.WriteLine("Element named {0} has type {1}", leafElement.Name, DirectCast(leafElement.GetSchemaInfo().SchemaType, XmlSchemaSimpleType).Datatype.TypeCode)

Next

With the XML file being

<?xml version="1.0" encoding="utf-8" ?>
<persons>
  <person>
    <last-name>  Watson  </last-name>
    <foo>false</foo>
  </person>
</persons>

and the schema being

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="persons">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="person" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="last-name" type="xs:normalizedString" />
              <xs:element name="foo" type="xs:boolean"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

that sample outputs

Element named last-name has type NormalizedString
Element named foo has type Boolean

So explore the SOM documentation on MSDN or in your local VS documentation, you should be able to find the information that way.


Don't attempt to do this by hand.

I'm not familiar with Linq, so there might be other ways of doing this, but one way is to use schema-aware XSLT or XQuery. If you process your validated document using a schema-aware XSLT or XQuery processor then you will be able to do tests like

if (. instanceof attribute(*, xs:normalizedString)) ...

which is true if the context node is an attribute node that was validated against an attribute declaration whose governing type is xs:normalizedString.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜