从架构确定元素和属性的基本类型

时间:2011-02-17 15:07:18

标签: xml vb.net xsd linq-to-xml

我已经给出了元素或属性的本地名称以及文档的架构。确定元素或属性的基本数据类型的最简单方法是什么。基本数据类型我指的是xs:string,xs:date等(xml架构的内置数据类型。)

我面临的一个问题是,元素类型很少是基本的内置类型之一。 99%的时间它是复杂类型,50%的时间是指另一种复杂类型,指的是另一种复杂类型,等等。

此架构的一个简单示例:我想找到Employee / Person / Name / LastName的基本类型(确定LastName是xs:normalizedString)。 在模式中,Employee被定义为xs:element和type =“bns:EmployeeType”

EmplyeeType定义了一个Person元素但它是类型“PersonType”,然后Name in person是NameType,它是一个复杂类型,它扩展了类型为BasicNameType的GeneralName类型,该类型最终定义了类型为“LastNameType”的LastName等等。还有定义等。

我目前正在使用linq-to-xml编写一个解析器来实现此目的,但这并不容易或漂亮。我已经搜索了其他解决方案,但没有找到任何解决方案,但我完全承认我的XML /架构/ XPath无知。

有没有简单的方法来获取元素的基本类型?

2 个答案:

答案 0 :(得分:4)

.NET框架有schema object model (SOM),并且在使用XmlReader验证或验证System.Xml.XmlDocument或System.Xml.Linq.XDocument后,可以使用钩子来访问模式类型。下面的示例演示如何验证System.Xml.Linq.XDocument以及如何访问架构信息:

    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

XML文件

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

,架构为

<?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>

该样本输出

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

因此,请浏览MSDN或本地VS文档中的SOM文档,您应该能够找到相应的信息。

答案 1 :(得分:1)

请勿尝试手动执行此操作。

我不熟悉Linq,所以可能有其他方法可以做到这一点,但一种方法是使用模式感知的XSLT或XQuery。如果您使用架构感知的XSLT或XQuery处理器处理经过验证的文档,那么您将能够执行类似

的测试
if (. instanceof attribute(*, xs:normalizedString)) ...

如果上下文节点是针对其管理类型为xs:normalizedString的属性声明进行验证的属性节点,则为true。

相关问题