Как я могу использовать аннотации в XSD для сопоставления целых чисел XML с соответствующими описаниями? - PullRequest
2 голосов
/ 01 июля 2010

Я пишу XSLT для превращения файла XML в удобочитаемую HTML-страницу.

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

Отображенные строки доступны в аннотациях в XSD.

Например:

<typewoning>1</typewoning>

После объявления XSD:

<xs:element name="typewoning" type="TypeWoningEnum"/>

Карты для:

    <xs:simpleType name="TypeWoningEnum">
    <xs:restriction base="xs:integer">
        <xs:enumeration value="1">
            <xs:annotation>
                <xs:documentation>vrijstaande woning</xs:documentation>
            </xs:annotation>
        </xs:enumeration>
        <xs:enumeration value="2">
            <xs:annotation>
                <xs:documentation>twee-onder-een-kap/rijwoning hoek</xs:documentation>
            </xs:annotation>
        </xs:enumeration>

и т. Д.

Так что в этом случае я хочу отобразить аннотацию для значения 1, которое должно быть «vrijstaande woning».

Какой лучший способ приблизиться к этому? Я не настолько опытен в XML / XSLT, чтобы знать о каком-либо из этих решений, и мои поиски в Google ничего не дали.

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 01 июля 2010

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

Предполагая, что в определенный момент ваша таблица стилей XSLT находится в положении, где typewoning находится под элементом контекста (т.е. value-of select="typewoning" будет выводить его значение), вы можете сделать это:

<xsl:variable name="schema" select="document('my-schema.xsd')/xsd:schema"/>

<xsl:variable name="type" select="$schema//xsd:simpleType[@name = 'TypeWoningEnum']"/>

<xsl:variable name="value" select="$type//xsd:enumeration[@value = typewoning]//xsd:documentation"/>

<xsl:value-of select="$value"/>

Некоторые объяснения:

  1. Первый шаг загружает схему в переменную с помощью функции документа XSL
  2. На втором шаге будет найден правильный тип (вы, вероятно, можете придумать и найти тип, используя тип элемента в документе, но тогда потребуется проверка схемы, и вам потребуется механизм XSLT, совместимый со схемой)
  3. Третий шаг находит значение документации для вывода, учитывая содержимое вашего элемента typewoning.

Четвертый шаг записывает результат, используйте по своему усмотрению.

Редактировать: альтернатива, если вы хотите использовать XSLT-механизм, совместимый со схемой, такой как платная версия saxon . Предполагая, что все ваши перечисления происходят от integer, вы можете попробовать это в контексте некоторого родительского узла:

<xsl:variable name="schema" select="document('my-schema.xsd')/xsd:schema"/>

<xsl:for-each select="element(*, xsd:integer)">
    <xsl:variable name="type" select="$schema//xsd:simpleType[@name = local-name(current())]"/>

    <xsl:if test="$type">
        <xsl:variable name="value" select="$type//xsd:enumeration[@value = current()/text()]//xsd:documentation"/>

        <xsl:text>Value: </xsl:text> <xsl:value-of select="$value"/>
    </xsl:if>
</xsl:for-each>
2 голосов
/ 05 июля 2010

Я потратил на это время и силы, я решил написать XSLT для преобразования схемы в отображение на основе документации перечисления, найденной в каждом xs: simpleType.

Этот код:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">

<xsl:output method="xml" version="1.0"
    encoding="utf-8" indent="yes"/>

<xsl:strip-space elements="*"/>

<xsl:template match="xs:schema">
    <mappings>
        <xsl:for-each select="//xs:element[contains(@type, 'Enum')] | //xs:element[contains(@type, 'JaNee')]">
            <xsl:variable name="type" select="@type" />
            <xsl:element name="{concat(@name, 'Mapping')}" >
                <xsl:apply-templates select="//xs:simpleType[@name=$type]">
                    <xsl:with-param name="elemname" select="@name" />
                </xsl:apply-templates>
            </xsl:element>
        </xsl:for-each>
    </mappings>
</xsl:template>

<xsl:template match="xs:enumeration">
    <xsl:param name="elemname" select="'undefined'" />
    <xsl:element name="{$elemname}">
        <xsl:attribute name="value">
            <xsl:value-of select="@value" />
        </xsl:attribute>
        <xsl:value-of select="xs:annotation/xs:documentation" />
    </xsl:element>
</xsl:template>

Выводит именно то, на что я надеялся:

    ...snip...
   <typewoningMapping>
      <typewoning value="1">vrijstaande woning</typewoning>
      <typewoning value="2">twee-onder-een-kap/rijwoning hoek</typewoning>
      <typewoning value="3">rijwoning tussen</typewoning>
      <typewoning value="4">galerijflat (hoogbouw)</typewoning>
      <typewoning value="5">portiekflat (etage)</typewoning>
      <typewoning value="6">maisonnettewoning</typewoning>
      <typewoning value="7">flatwoning (overig)</typewoning>
      <typewoning value="8">woongebouw met niet-zelfstandige woonruimte</typewoning>
   </typewoningMapping>
   ...snip...

Теперь мне осталось написать только то, что делает xsl с тегами xsl: key, определенными для сопоставленийЯ хочу использовать.

Спасибо всем за помощь в этом.

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