XSLT:条件文本排除/替换

时间:2018-11-01 14:06:26

标签: xml xslt

我的任务是作为POC第一次做一些xslt并绊倒解决方案。我的问题 能够在发生匹配时用我的函数返回的内容替换节点的内容。在 我在将它们放在一起时遇到问题,使得run标签内的原始文本也无法通过 因为当测试为TRUE时,应将其替换为我的handle-links函数定义的内容。 michael.hor257k给了 在上一篇文章中针对我的问题提供了一些好的建议,该文章现已关闭,但是我仍然对正确的语法感到困惑 我需要申请以达到预期的结果。如果有人可以帮助我做出正确的修改,那将是 非常感谢。

给出以下XML。

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <par def='15'>
        <run>
            <font size='8pt' name='Verdana' pitch='variable' truetype='true'
 familyid='20' color='navy'/>[&lt;a href="www.google.com.au" target="_new"&gt;Google&lt;/a&gt;]
        </run>
    </par>
</catalog>

并应用正确的XSLT(我需要协助)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <html>
            <body>
                <h2>My Transform</h2>  
                <xsl:apply-templates/>  
            </body>
        </html>
    </xsl:template>

    <xsl:template match="run">
        <font name='Verdana' size='14pt'>
            <xsl:call-template name="handle-links">
                <xsl:with-param name="txt" select="."/>
            </xsl:call-template>
        </font>
    </xsl:template>

    <xsl:template name="handle-links">

        <xsl:param name="txt"/>

        <xsl:if
            test="contains($txt,'[&lt;a')">

            <xsl:variable name="quotes">"</xsl:variable>    

            <!-- Get URL -->
            <xsl:variable name="urlVar" select='substring-before(substring-after($txt, $quotes), $quotes)'/> 

            <!-- Get Link Name -->
            <xsl:variable name="linkName" select='substring-before(substring-after($txt, "&gt;"), "&lt;")'/> 

            <a href="{$urlVar}">
                <xsl:value-of select="$linkName"/>
            </a>
        </xsl:if>

    </xsl:template>

</xsl:stylesheet>

我正在尝试实现以下条件,并且仅当测试test =“ contains($ txt,'[是真的时才能实现。

<font name='Verdana' size='14pt'>
    <a href="www.google.com">Google</a>
</font>

如果测试test="contains($txt,'[&lt;a')">为FALSE,那么我只希望<font name = 'Verdana' size='14pt'> </font>标签包围run元素的text()内容。

干杯

1 个答案:

答案 0 :(得分:1)

一种方法是使用xsl:choose代替xsl:if

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <body>
        <h2>My Transform</h2>  
        <xsl:apply-templates/>  
      </body>
    </html>
  </xsl:template>

  <xsl:template match="run">
    <font name='Verdana' size='14pt'>
      <xsl:call-template name="handle-links">
        <xsl:with-param name="txt" select="."/>
      </xsl:call-template>
    </font>
  </xsl:template>

  <xsl:template name="handle-links">
    <xsl:param name="txt"/>
    <xsl:choose>
     <xsl:when test="contains($txt,'[&lt;a')">
        <xsl:variable name="quotes">"</xsl:variable>  
          <!-- Get URL -->
        <xsl:variable name="urlVar" select='substring-before(substring-after($txt, $quotes), $quotes)'/> 
          <!-- Get Link Name -->
        <xsl:variable name="linkName" select='substring-before(substring-after($txt, "&gt;"), "&lt;")'/> 

        <a href="{$urlVar}">
          <xsl:value-of select="$linkName"/>
        </a>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$txt" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

另一种方法是让模板匹配文本节点,而不是命名模板,并使模板中的条件匹配。也尝试一下

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <body>
        <h2>My Transform</h2>  
        <xsl:apply-templates/>  
      </body>
    </html>
  </xsl:template>

  <xsl:template match="run">
    <font name='Verdana' size='14pt'>
      <xsl:apply-templates select="text()" />
    </font>
  </xsl:template>

  <xsl:template match="run/text()[contains(.,'[&lt;a')]">
    <xsl:variable name="quotes">"</xsl:variable>  
      <!-- Get URL -->
    <xsl:variable name="urlVar" select='substring-before(substring-after(., $quotes), $quotes)'/> 
      <!-- Get Link Name -->
    <xsl:variable name="linkName" select='substring-before(substring-after(., "&gt;"), "&lt;")'/> 

    <a href="{$urlVar}">
      <xsl:value-of select="$linkName"/>
    </a>
  </xsl:template>
</xsl:stylesheet>

在文本不包含链接的情况下,XSLT的内置模板将仅正常输出文本。

http://xsltfiddle.liberty-development.net/pPqsHUn处查看实际操作(该网站对于实验和调试非常有用。它还支持XSLT 3.0,如果可以使用XSLT 3.0,则可以使用parse-xml命令来可能会使创建链接更容易)。