XPath:在复制所有XML时,仅将文本附加到最后一个text()出现(无论嵌套的程度有多深)。

时间:2017-08-04 00:46:12

标签: xslt xpath xslt-1.0

在XML文件上使用XSLT,我的目标是复制所有XML,同时将一段文本("(PDF)"在此示例中)附加到特定文本中的最后一位文本标记,无论下一个嵌套的深度如何。我已经成功处理了大部分边缘情况并将其关闭,但仍有一个例子给我带来了麻烦。我确信还有一种方法可以更有效地完成这项工作,所以我们非常感谢任何提示。

XML

<links>
    <a href="something.pdf">This is a PDF file</a>
    <a href="something.PDF">
        <span>
            <b>This</b> is a PDF file
        </span>
    </a>
    <a href="something.pdF">
        <div>
            <span>
                This is a PDF file
            </span>
        </div>
    </a>
    <a href="something.pdf">
        <div class="something">
            <span>
                This is a <i>PDF</i> file
            </span>
        </div>
    </a>
    <a href="something.pDf">
        <div class="something">
            <div>
                <div>
                    Test Text
                    <div>
                        This is a <i>PDF</i>
                    </div>
                </div>
            </div>
        </div>
    </a>
</links>

XSLT

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

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

    <xsl:param name="pdf-append" select="'(PDF)'"/>

    <xsl:template match="a['.pdf' = substring(translate(@href,'PDF','pdf'), string-length(@href) - 3)]/text()">
        <xsl:value-of select="concat(current(),' ', $pdf-append)"/>
    </xsl:template>

    <xsl:template match="a['.pdf' = substring(translate(@href,'PDF','pdf'), string-length(@href) - 3)]//node()[last()]/text()[last()]">
        <xsl:value-of select="concat(current(),' ', $pdf-append)"/>
    </xsl:template>
</xsl:stylesheet>

当前结果

<links>
<a href="something.pdf">This is a PDF file (PDF)</a>
   <a href="something.PDF">
      <span>
         <b>This</b> is a PDF file
         (PDF)</span>
   </a>
   <a href="something.pdF">
      <div>
         <span>
                This is a PDF file
             (PDF)</span>
      </div>
   </a>
   <a href="something.pdf">
      <div class="something">
         <span>
                This is a <i>PDF</i> file
             (PDF)</span>
      </div>
   </a>
   <a href="something.pDf">
      <div class="something">
         <div>
            <div>
                    Test Text
                     (PDF)<div>
                        This is a  (PDF)<i>PDF (PDF)</i>
               </div>
            </div>
         </div>
      </div>
   </a>
</links>

最后<a>是问题:理想情况下&#34;(PDF)&#34;只会出现在最后一个<i>标记内(例如This is a <i>PDF (PDF)</i>)。所以问题是:我如何修复最后一个实例?

感谢。

1 个答案:

答案 0 :(得分:0)

怎么样:

XSLT 1.0

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

<xsl:param name="pdf-append" select="' (PDF)'"/>

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

<xsl:template match="text()">
    <xsl:value-of select="."/>

    <xsl:variable name="a" select="ancestor::a" />
    <xsl:variable name="href" select="$a/@href" />
    <xsl:variable name="extension" select="substring(translate($href,'PDF','pdf'), string-length($href) - 3)" />
    <xsl:variable name="last-text" select="$a/descendant::text()[last()]" />

    <xsl:if test="$extension='.pdf' and generate-id()=generate-id($last-text) ">
        <xsl:value-of select="$pdf-append"/>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>