XSLT Преобразование для вывода элемента, если он отсутствует в источнике, если он присутствует, оставив его без изменений.

В основном у меня есть исходный XML

<RootElement attr=yes>
     <parentElement>
        <ChildElement1>some value in str</ChildElement1>
        <ChildElement2>some value in str</ChildElement2>
        <ChildComplexType1>
              <grandChildElement1>some value in str</grandChildElement1>
         </ChildComplexType1>
     </parentElement>
</RootElement>

Я использую XSLT, чтобы изменить его на какой-то другой XML. Потребитель, получающий XML-результат, ожидает, как показано ниже

<RootElement attr=yes>
         <parentElement>
            <ChildElement1>some value in str</ChildElement1>
            <ChildElement2>some value in str</ChildElement2>
            <ChildComplexType1>
                  <grandChildElement1>some value in str</grandChildElement1>
                  <grandChildElement2>Default Value/ From Source XML</grandChildElement2>
             </ChildComplexType1>
         </parentElement>
    </RootElement>

Проблема в том, что я использую приведенное ниже правило соответствий, и оно не работает. Кто-нибудь может предложить лучшее правило, которое работает? Я считаю, что это основной вопрос, извиняюсь, так как я новичок в XSLT.

<xsl:template match="@*|node()" priority="1">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*:parentElement"
        priority="2">
        <xsl:element name="{name()}"
            namespace="http://namespace"
            inherit-namespaces="no">
            <xsl:namespace name="ns5"
                select="'namespace'" />
            <xsl:apply-templates select="@*|node()" />
        </xsl:element>
    </xsl:template>

<xsl:template match="*:ChildComplexType1">
            <xsl:if test="not(*:grandChildElement2)" priority="3">
                <grandChildElement2>defaultValue</grandChildElement2>
            </xsl:if>
            <xsl:apply-templates />
        </xsl:template>

2 ответа

Я думаю, что проблема с использованием атрибута "priority" в шаблоне идентификации

<xsl:template match="@*|node()" priority="1">

Это дало ему более высокий приоритет, чем сопоставление с шаблоном *::ChildComplexType1и поэтому этот шаблон никогда не совпадает.

Попробуйте удалить приоритеты, вот так:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="@*|node()">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*:parentElement">
        <xsl:element name="{name()}"
            namespace="http://namespace"
            inherit-namespaces="no">
            <xsl:namespace name="ns5"
                select="'namespace'" />
            <xsl:apply-templates select="@*|node()" />
        </xsl:element>
    </xsl:template>

    <xsl:template match="*:ChildComplexType1">
        <xsl:copy>
            <xsl:apply-templates />
            <xsl:if test="not(*:grandChildElement2)">
                <grandChildElement2>defaultValue</grandChildElement2>
            </xsl:if>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Обратите внимание, что я добавил xsl:copy к ChildComplexType1 шаблон, но вы, кажется, делаете что-то с пространствами имен, которые вы не упомянули в своем вопросе, поэтому вам может потребоваться изменить это на xsl:element вместо.

Обратите внимание, см. http://www.w3.org/TR/xslt для получения информации о приоритете шаблона. В частности, обратите внимание, как самый высокий приоритет по умолчанию равен 0,5.

Кажется, вы используете шаблон идентификации.

Вы можете посмотреть на эту страницу, которая довольно подробно описывает шаблон.

http://www.xmlplease.com/xsltidentity.

Другие вопросы по тегам