Использование xslt для преобразования нескольких документов XML-схемы - PullRequest
4 голосов
/ 03 декабря 2011

У меня есть ряд документов XML-схемы, которые используются для описания параметров конфигурации моего приложения.Схемы XML выглядят следующим образом:

Client.xsd

<xsd:schema targetNamespace="http://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:complexType name="Client">
        <xsd:attribute name="Host" type="xsd:string>
    </xsd:complexType>

</xsd:schema>

Server.xsd

<xsd:schema targetNamespace="http://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:complexType name="Server">
        <xsd:attribute name="Port" type="xsd:unsignedShort>
        <xsd:attribute name="MaxConnections" type="xsd:int default="32">
    </xsd:complexType>

</xsd:schema>

Application.xsd

<xsd:schema targetNamespace="http://www.example.com/core"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:complexType name="Application">
        <xsd:attribute name="Name" type="xsd:string>
        <xsd:attribute name="Id" type="xsd:int>
    </xsd:complexType>

</xsd:schema>

FooClient.xsd

<xsd:schema targetNamespace="http://www.example.com/foo"
            xmlns:core="network://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:import namespace="http://www.example.com/network"
                schemaLocation="client.xsd"/>

    <xsd:complexType name="FooClient">
        <xsd:complexContent>
            <xsd:extension base="network:Client">
                <xsd:attribute name="foo" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

</xsd:schema>

FooServer.xsd

<xsd:schema targetNamespace="http://www.example.com/foo"
            xmlns:core="network://www.example.com/network"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:import namespace="http://www.example.com/network"
                schemaLocation="client.xsd"/>

    <xsd:complexType name="FooServer">
        <xsd:complexContent>
            <xsd:extension base="network:Server">
                <xsd:attribute name="foo" type="xsd:string"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

</xsd:schema>

FooApplication.xsd

<xsd:schema targetNamespace="http://www.example.com/foo"
            xmlns:core="http://www.example.com/core"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:import namespace="http://www.example.com/core"
                schemaLocation="Application.xsd"/>

    <xsd:include schemaLocation="FooClient.xsd"/>
    <xsd:include schemaLocation="FooServer.xsd"/>

    <xsd:complexType name="FooApplication">
        <xsd:complexContent>
            <xsd:extension base="core:Application">
                <xsd:sequence>
                    <xsd:element name="FooInput" type="FooClient"/>
                    <xsd:element name="FooOutput" type="FooServer"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:element name="Foo" type="FooApplication"/>

</xsd:schema>

Это пример экземпляра документа:

<foo:Foo xmlns:foo="http://www.example.com/foo" 
         Id="1234"
         Name="FooInstance1">

    <FooInput Host="localhost:12345"
              Name="Input"
              foo="bar"/>

    <FooOutput Port="54321"
               Name="Output"
               foo="bar"/>

</foo:Foo>

Моя цель - взять документ схемы FooApplication и превратить его в удобочитаемую форму, чтобы люди, ответственные за поддержку приложения, точно знали, какие параметры конфигурации доступны, типы данных, значения по умолчанию и т. Д. В конце концов ядобавит элементы документации, которые также могут быть добавлены к выводу, но сейчас я пытаюсь сделать это простым.Таким образом, приведенный выше пример может выглядеть примерно так:

FooApplication/Id, int
FooApplication/Name, string
FooApplication/FooInput/Host, string
FooApplication/FooInput/foo, string
FooApplication/FooOutput/Port, unsignedShort
FooApplication/FooOutput/MaxConnections, int, default=32
FooApplication/FooOutput/foo, string

Для этой задачи xslt кажется очевидным инструментом.Однако мне трудно разобраться, как получить данные из нескольких документов.Я пробовал что-то вроде этого (например, для индексации всех элементов complexType):

<xsl:template match="xsd:include">
    <xsl:apply-templates select="document(@schemaLocation)"/>
</xsl:template>

<xsl:template match="xsd:import">
    <xsl:apply-templates select="document(@schemaLocation)"/>
</xsl:template>

<xsl:key name="complexType" match="xsd:complexType" use="@name"/>

Однако при использовании ключа разрешается только complexType из FooApplicaiton.xsd.

У кого-нибудь естьЛюбое понимание того, как этого можно достичь?

Большое спасибо заранее.

Ответы [ 4 ]

0 голосов
/ 05 декабря 2011

Спасибо, Петру Гардя , за упоминание нашего инструмента DocFlex / XML XSDDoc !

Да, действительно, используя нашу документацию XML-схемы, можно задокументировать все эти примеры XML-схем, упомянутых в первоначальном вопросе.

Вот такой документ, который я только что сгенерировал:

http://www.filigris.com/pr/stackoverflow.com/questions/8369677/using-xslt-to-transform-multiple-xml-schema-documents/xsddoc/

Но я должен сказать, что предоставленные списки XSD несколько неверны. Если вы воспринимаете эти тексты буквально и создаете из них соответствующие XSD-файлы, ничего не получится! (Для создания документа мне нужно было их исправить.)

Во-первых, разметка XML в некоторых схемах просто недопустима (например, в Application.xsd).

Во-вторых, FooApplication.xsd использует неправильные ссылки на типы. Он определяет элементы «FooInput» и «FooOutput» с типами «FooClient» и «FooServer» соответственно. Эти типы определены в FooClient.xsd и FooServer.xsd, которые включены в FooApplication.xsd. Все в порядке. Чего здесь не хватает, так это того, что эти типы определены в пространстве имен: "http://www.example.com/foo". Но местоположения XML в FooApplication.xsd, где они используются, связаны с другим пространством имен - по умолчанию (т.е. без пространства имен ). Итак, декларация:

<xsd:element name="FooInput" type="FooClient"/>

фактически не относится к типу:

{http://www.example.com/foo}:FooClient

а точнее к типу:

{no namespace}:FooClient

Чтобы ссылки на типы были правильными, вам нужно добавить еще одну привязку пространства имен в в FooApplication.xsd:

<xsd:schema targetNamespace="http://www.example.com/foo"
        xmlns="http://www.example.com/foo"
        xmlns:core="http://www.example.com/core"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">

или используйте дополнительный префикс пространства имен, связанный с "http://www.example.com/foo".

Итак, если вы когда-либо пытались документировать исходные схемы напрямую с помощью нашего инструмента DocFlex / XML XSDDoc , очевидно, что вы не получили бы правильной документации!

(Наша XML-схема doc-gen не проверяет какую-либо XML-схему автоматически. Она просто не может этого сделать, потому что, во-первых, это не ее работа, а во-вторых, любая проверка схемы потребует дополнительного времени обработки, что может раздражать большинство кто уверен, что их схемы верны. В конце концов, вы всегда можете добавить дополнительный шаг проверки схемы в свой файл сборки)

Наконец , если все вышеперечисленное не касается вас - то есть все эти ошибки в примерах схем - просто неточности этого конкретного вопроса - тогда было бы действительно интересно узнать, почему наши инструмент не подходит для вашей задачи (кроме коммерческих, финансовых или организационных вопросов).

Петру Гардея предположил, что наше решение может быть «расширено». Но в каком направлении, вообще, может быть необходимо увеличить его? Это было бы действительно интересно услышать! Потому что это наша собственная задача - как сделать наш инструмент документирующим схемы XML еще лучше.

приписка На этом сайте есть еще один вопрос, который также очень связан с этой темой:

Как преобразовать xsd в удобочитаемую документацию?

Я также предоставил ответ (хотя некоторые могут считать его спорным, особенно с точки зрения мейнстрима). К сожалению, к тому времени у меня не было этой учетной записи, поэтому я не могу напрямую к ней относиться.

0 голосов
/ 03 декабря 2011

Я бы начал с рассмотрения DocFlex и выяснил, имеет ли для вас смысл их подход к документации XML-схемы. Затем вы сможете масштабировать вверх или вниз. Для чего-то, кроме тривиального, если бы вам пришлось создавать свою собственную систему документации, я бы подумал, что она должна быть основана на API объектной модели схемы XML (XSOM) с этим созданием XML, который затем может быть представлен с использованием XSLT ...

0 голосов
/ 04 декабря 2011

Причина, по которой xsl: key не работает для вас, заключается в том, что он выполняет поиск только в одном документе. Решением может быть создание составного документа (в переменной xsl:), который объединяет содержимое различных документов схемы, и затем использование xsl: key для этого.

(Или используйте Saxon-EE, который будет создавать индексы автоматически, где это необходимо, избегая необходимости явных ключей.)

Как правило, манипулирование необработанными документами схемы с использованием XSLT является сложным, поскольку в XSD существует множество разных способов написания одной и той же вещи. Однако, если у вас есть контроль над стилем кодирования, используемым в документах схемы, этого вполне возможно достичь.

0 голосов
/ 03 декабря 2011

Вам не нужно обрабатывать схемы каким-либо образом, кроме лучшего написания схем.

Используйте элемент xs:annotation и его дочерний элемент xs:documentation в максимально возможной степени в любом месте, где разрешено xs:annotation .

Затем вы можете создавать экземпляры своих схем с помощью хорошего редактора XML, такого как XML-редактор Visual Studio , и автоматически определять значение IDE:

  • Отображает аннотации (которые описывают значение и тип).
  • Запрашивает / перечисляет возможные имена и значения для атрибутов и возможных дочерних элементов. Для всех этих при выборе (до нажатия Enter) их соответствующие аннотации также отображаются с помощью intellisense.

Редактор XML также помечает красным цветом все ошибки, а в окне «Ошибки» отображаются все сообщения об ошибках или предупреждения - все это в режиме реального времени, когда пользователь вводит документ XML.

Наконец : Если после создания аннотаций вы все еще хотите создать что-то вроде отдельной (или даже напечатанной) документации, вы можете легко обработать схемы с помощью XSLT и просто вывести доступные аннотации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...