Определить основные типы элементов и атрибутов из схемы - PullRequest
0 голосов
/ 17 февраля 2011

Я дал локальное имя элемента или атрибута и схему для документа. Какой самый простой способ определить базовый тип данных элемента или атрибута. Под базовым типом данных я подразумеваю 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, который представляет собой сложный тип, который расширяет тип GeneralName, который является типом BasicNameType, и этот тип, наконец, определяет LastName, который имеет тип «LastNameType» и так далее. Там также определения и т. Д.

В настоящее время я пишу парсер с использованием linq-to-xml, но это не просто и не красиво. Я искал другие решения и не нашел ни одного, но полностью признаю свое незнание XML / schema / XPath.

Есть ли простой способ получить базовый тип для элементов?

Ответы [ 2 ]

4 голосов
/ 17 февраля 2011

.NET Framework имеет объектную модель схемы (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

Так что изучите документацию SOM на MSDN или в своей локальной документации VS, вы сможете найти информацию таким образом.

1 голос
/ 17 февраля 2011

Не пытайтесь сделать это вручную.

Я не знаком с Linq, поэтому могут быть и другие способы сделать это, но один из них - использовать XSLT или XQuery с поддержкой схемы.Если вы обработаете ваш проверенный документ с использованием процессора XSLT или XQuery, поддерживающего схему, то вы сможете выполнять такие тесты, как

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

, что верно, если узел контекста является узлом атрибута, который был проверен по атрибутуобъявление, управляющим типом которого является xs: normalizedString.

...