Как написать преобразование идентичности в XSLT, которое сохраняет дочерние элементы выбранных узлов? - PullRequest
2 голосов
/ 04 февраля 2011

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

Я выполняю преобразование XML в XML, пытаясь изолировать и скопировать только несколько элементов большого файла схемы.Вот упрощенная версия данных:

Источник XSD

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" version="1.0">

<xsd:simpleType name="Alpha">
    <xsd:restriction base="xsd:decimal">
        <xsd:fractionDigits value="1"/>
        <xsd:minInclusive value="0.0"/>
        <xsd:maxInclusive value="100.0"/>
    </xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="Bravo">
    <xsd:annotation>
        <xsd:documentation>
            Bravo data type.
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:integer"/>
</xsd:simpleType>

<xsd:simpleType name="Charlie">
    <xsd:annotation>
        <xsd:documentation>
        Charlie data type.
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:integer"/>
</xsd:simpleType>

<xsd:simpleType name="Delta">
    <xsd:annotation>
        <xsd:documentation>
        Delta data type.
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
</xsd:schema>

Таблица стилей XSLT

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />   
<!-- identity template -->
<xsl:template match="/ | node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*/node()[ 
                               not ( @name='Alpha')
                               and  
                               not ( @name='Charlie')
                                ]

                               "/>
</xsl:stylesheet>

Результаты

<?xml version="1.0"?>
<xsd:schema attributeFormDefault="unqualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:simpleType name="Alpha"></xsd:simpleType>
<xsd:simpleType name="Charlie"></xsd:simpleType>
</xsd:schema>

Это действительно близко, но мне нужны дочерние элементы выбранных узлов Альфа и Чарли в результатах, как если бы я выполнил copy-of.

Что мне нужно

<?xml version="1.0"?>
<xsd:schema attributeFormDefault="unqualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:simpleType name="Alpha">
        <xsd:restriction base="xsd:decimal">
        <xsd:fractionDigits value="1"/>
        <xsd:minInclusive value="0.0"/>
        <xsd:maxInclusive value="100.0"/>
    </xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Charlie">
    <xsd:annotation>
        <xsd:documentation>
            Charlie data type.
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:integer"/>
</xsd:simpleType>
</xsd:schema>

Есть ли способ выбрать элементы с помощью copy-of, или указать в моем предложении match, что я хочу использоватьв детей Альфы и Чарли?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 04 февраля 2011

Или, в качестве альтернативы хорошему ответу @Alejandro, вы можете исправить проблемы в своем коде :

Просто изменить :

<xsl:template match=
 "*/node()[
           not ( @name='Alpha')
          and
           not ( @name='Charlie')
           ]
  "/>

до :

<xsl:template match=
 "/*/node()[
           not ( @name='Alpha')
          and
           not ( @name='Charlie')
           ]
  "/>

Объяснение : Первоначально предоставленный «шаблон удаления» соответствует слишком большому количеству узлов.Он должен соответствовать только дочерним элементам верхнего элемента.

2 голосов
/ 04 февраля 2011

Вы должны обратить свою логику в скопировать все, кроме элементов "Bravo" и "Delta" .

Пустой шаблон будет выглядеть так:

<xsl:template match="xs:simpleType[@name[.='Bravo' or .='Delta']]"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"/> 

Примечание : добавление пространства имен на всякий случай ...

Другой способ, более семантический:

<xsl:template match="/*/*[not(@name[.='Alpha' or .='Charlie'])]"/> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...