如果特定标签已经存在,则在同一级别附加多个标签

Append multiple tags on same level if a specific tag is already there

我现在改了很多次我的xsl,但我没有找到正确的方法。现在这就是我想要的:

我现在试图找到所有丢失的页面,这些页面没有描述。如果缺少,我想为该页面添加描述,如果存在,我想修改描述。 pageX 到 pageXDescription 的字符串始终相同。

这是我的简短示例 xml:

 <BOOK>
    <PAGE NAME='page1' VALUE='coolText'/>
    <PAGE NAME='Description1' VALUE='coolDescription'/>
    <PAGE NAME='page2' VALUE='moreText'/>
    <PAGE NAME='page3' VALUE='aLotMoreText'/>
    <PAGE NAME='Description3' VALUE='aLotMoreDescriptions'/>
  </BOOK>

我试过类似的东西:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- define output settings and header -->
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no" media-type="string" encoding="ISO-8859-1" doctype-system="deftable.dtd"/>

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

    <xsl:template match="BOOK[PAGE/@NAME='page1']">
        <xsl:copy>
            <xsl:call-template name="create_missing_description_pages">
                <xsl:with-param name="page" select="'page1'"/>
                <xsl:with-param name="description" select="'Description1'"/>
                <xsl:with-param name="new_description" select="'newContent'"/>
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="BOOK[PAGE/@NAME='page2']">
        <xsl:copy>
            <xsl:call-template name="create_missing_description_pages">
                <xsl:with-param name="page" select="'page2'"/>
                <xsl:with-param name="description" select="'Description2'"/>
                <xsl:with-param name="new_description" select="'newContent'"/>
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="BOOK[PAGE/@NAME='page3']">
        <xsl:copy>
            <xsl:call-template name="create_missing_description_pages">
                <xsl:with-param name="page" select="'page3'"/>
                <xsl:with-param name="description" select="'Description3'"/>
                <xsl:with-param name="new_description" select="'newContent'"/>
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>
    <!-- Function to generate missing XML Tags -->
    <xsl:template name="create_missing_description_pages">
        <xsl:param name="page"/>
        <xsl:param name="description"/>
        <xsl:param name="new_description"/>
        <xsl:apply-templates select="@*|VARIABLE[@NAME=$page]/preceding-sibling::node()"/>
        <xsl:apply-templates select="VARIABLE[@NAME=$page]"/>
        <xsl:if test="not(VARIABLE/@NAME=$description)">
            <xsl:element name="PAGE">
                <xsl:attribute name="NAME"><xsl:value-of select="$description"/></xsl:attribute>
                <xsl:attribute name="VALUE"><xsl:value-of select="$new_description"/></xsl:attribute>
            </xsl:element>
        </xsl:if>
        <xsl:apply-templates select="VARIABLE[@NAME=$page]/following-sibling::node()"/>
    </xsl:template>
    <xsl:template match="BOOK/PAGE">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="@NAME='Description1'">
                    <xsl:attribute name="NAME"><xsl:value-of select="@NAME"/></xsl:attribute>
                    <xsl:attribute name="VALUE">newContent</xsl:attribute>
                </xsl:when>
                <xsl:when test="@NAME='Description2'">
                    <xsl:attribute name="NAME"><xsl:value-of select="@NAME"/></xsl:attribute>
                    <xsl:attribute name="VALUE">newContent</xsl:attribute>
                </xsl:when>
                <xsl:when test="@NAME='page3Description'">
                    <xsl:attribute name="NAME"><xsl:value-of select="@NAME"/></xsl:attribute>
                    <xsl:attribute name="VALUE">newContent</xsl:attribute>
                </xsl:when>
                <!-- other child items will just be copied -->
                <xsl:otherwise>
                    <xsl:copy-of select="@*"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这就是我在所有情况下所期望的,如果所有描述都缺失,或者如果所有描述都可用:

  <BOOK>
    <PAGE NAME='page1' VALUE='coolText'/>
    <PAGE NAME='Description1' VALUE='newContent'/>
    <PAGE NAME='page2' VALUE='moreText'/>
    <PAGE NAME='Description2' VALUE='newContent'/>
    <PAGE NAME='page3' VALUE='aLotMoreText'/>
    <PAGE NAME='Description3' VALUE='newContent'/>
  </BOOK>

如果没有page3,那我也不要page Description。

我希望如此,这是可以理解的。

非常感谢您的提示,我的逻辑错误在哪里以及如何解决它。

此致 比约恩

你能不能简单点:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="PAGE">
    <xsl:variable name="pagenum" select="xs:integer(substring-after(@NAME, 'page'))" />
    <xsl:copy-of select="."/>
    <PAGE NAME='Description{$pagenum}'>
        <xsl:attribute name="VALUE">
            <xsl:choose>
                <xsl:when test="$pagenum=1">newContent1</xsl:when>
                <xsl:when test="$pagenum=2">newContent2</xsl:when>
                <xsl:when test="$pagenum=3">newContent3</xsl:when>
            </xsl:choose>
        </xsl:attribute>
     </PAGE>    
</xsl:template>

<xsl:template match="PAGE[starts-with(@NAME, 'Description')]"/>

</xsl:stylesheet>