Сортировка XML-схемы без переупорядочения дочерних элементов именованного элемента - PullRequest
0 голосов
/ 03 июля 2019

Мы генерируем XML-схемы из модели, но обнаруживаем, что это может привести к переупорядочению XML-схем с течением времени. Это не то, что мы можем легко контролировать, поэтому мы намерены применить XSLT-преобразование к сгенерированным XML-схемам, чтобы придать им более упорядоченный порядок.

Чтобы добиться этого, мы решили изменить порядок элементов на основе имени элемента, а затем атрибутов (в идеале name будет иметь приоритет над другими атрибутами).

т.е. заказать по

  1. <element> (имя элемента)
  2. <element name="xyz"> (атрибут «имя»)
  3. <element *="*"> (все остальные атрибуты)

Однако существует один набор элементов, для которых мы не можем переупорядочить дочерние элементы, который является <xs:sequence>, поскольку они в строгом порядке.

Пример определения, для которого нельзя изменить порядок, приведен ниже.

  <xs:complexType name="OBJECT.OtherSystemClaimsXref">
    <xs:sequence>
      <xs:group ref="FIELDS.OtherSystemClaimsXref"/>
      <xs:group ref="FIELDS.ExternallyMaintained"/>
      <xs:group ref="FIELDS.DtoSupplier"/>
      <xs:group ref="FIELDS.BusinessObject"/>
      <xs:group ref="FIELDS.OtherSystemXrefAbstract"/>
    </xs:sequence>
    <xs:attribute name="externalSystemReference" type="TYPE.OpenTwinsExternalReference" use="required"/>
    <xs:attribute name="dataChangedEnum" type="ENUM.DataChangedEnum" use="optional"/>
    <xs:attribute name="importable" type="xs:boolean" use="optional"/>
  </xs:complexType>

В качестве отправной точки я предложил приведенный ниже XSLT.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" omit-xml-declaration="no" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="node()">
                <xsl:sort select="name()" />
                <xsl:sort select="@*" order="ascending" data-type="text" />
                <xsl:sort select="." />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    <xsl:strip-space elements="*" />
</xsl:stylesheet>

Я попытался изменить поведение, предотвратив сортировку для <xs:sequence>, но это не сработало.

        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="*[not(local-name()='sequence')]">
                <xsl:sort select="name()" />
                <xsl:sort select="@*" order="ascending" data-type="text" />
                <xsl:sort select="." />
            </xsl:apply-templates>
            <xsl:apply-templates select="*[local-name()='sequence']"/>
        </xsl:copy>

Как я могу применить эти правила ко всему, кроме ближайших потомков <xs:sequence>?

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

1 Ответ

1 голос
/ 03 июля 2019

Если вы не хотите, чтобы дети xsl:sequence были заказаны, вы должны добавить для этого специальный шаблон, который будет иметь приоритет над вашим общим.

<xsl:template match="xs:sequence">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

Для этого потребуется объявить префикс пространства имен xs в таблице стилей.

Попробуйте это XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output indent="yes" omit-xml-declaration="no" />

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

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="node()">
                <xsl:sort select="name()" />
                <xsl:sort select="@*" order="ascending" data-type="text" />
                <xsl:sort select="." />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="xs:sequence">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...