Проблема с COPY Применить шаблон XSLT - PullRequest
4 голосов
/ 16 июня 2011

Я начал изучать XSLT совсем недавно и придумал сценарий. Исходная и целевая структура точно такие же, чего можно добиться с помощью приведенного ниже кода:

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

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

</xsl:stylesheet>

Но мое требование - создать целевой узел, только если выполнено одно из условий.

Пример, если

VNum eq 999

источник и цель должны выглядеть так:

Источник

 <POExt>
    <SD>01</SD>
    <PODet>
        <PNum schemeAgencyID="TEST">12345678</PNum>
        <VNum>999</VNum>
    </PODet>
    <PODet>
        <PNum schemeAgencyID="">45654654</PNum>
        <VNum>001</VNum>
    </PODet>
 </POExt>

Цель

 <POExt>
    <SD>01</SD>
    <PODet>
        <PNum schemeAgencyID="TEST">12345678</PNum>
        <VNum>999</VNum>
    </PODet>
 </POExt>

<PODet> повторяется каждый раз, когда он соответствует критериям VNum, если ни один из <PODet> не соответствует критериям, которые можно иметь

 <POExt>
    <SD>01</SD>
 </POExt>

Если вы хотите добиться этого, используя Copy и apply-templates, любая помощь будет высоко ценится.

Спасибо ..

1 Ответ

3 голосов
/ 16 июня 2011

При работе с правилом идентификации необходимо переопределить элементы путем сопоставления шаблонов.

В вашем случае вы не хотите копировать элементы PODet, которые не соответствуютопределенное условие.Согласно отрицательной логике, вам просто нужно «заткнуть» узлы, которые не соответствуют вашему состоянию.Например:

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

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

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

    <xsl:template match="PODet[not(VNum/text()=999)]"/>

</xsl:stylesheet>

Если ваш VNum является переменной, скажем входной параметр для вашего преобразования, в XSLT 2.0 вы можете просто сделать:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>

    <xsl:param name="VNum" select="999"/>

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

    <xsl:template match="PODet[not(VNum/text()=$VNum)]"/>

</xsl:stylesheet>

В XSLT 1.0 переменныене допускается в шаблоне совпадения шаблона, поэтому необходимо включить проверку условия внутри шаблона.Например, вы можете применять шаблоны только к элементам, соответствующим вашему условию:

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

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

    <xsl:param name="VNum" select="999"/>

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

    <xsl:template match="PODet">
        <xsl:apply-templates select="VNum[text()=$VNum]"/>
    </xsl:template>

    <xsl:template match="VNum">
        <xsl:copy-of select=".."/>
    </xsl:template>

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