【问题标题】:How to parse text nodes in xml using XSLT 2.0 functions如何使用 XSLT 2.0 函数解析 xml 中的文本节点
【发布时间】:2014-10-01 16:36:08
【问题描述】:

假设我有这个临时文件:

<xsl:variable name="var">
    <root>
        <sentence>Hello world</sentence>
        <sentence>Foo foo</sentence>
    </root>
</xsl:variable>

我正在使用分析字符串来查找“世界”字符串并用名为&lt;match&gt;的元素包装它

<xsl:function name="my:parse">
    <xsl:param name="input"/>
        <xsl:analyze-string select="$input" regex="world">
            <xsl:matching-substring>
                <match><xsl:copy-of select="."/></match>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:copy-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
</xsl:function>

这个函数将返回:

Hello <match>world</match>Foo foo

我当然想要这个输出:

    <root>
        <sentence>Hello <match>world</match></sentence>
        <sentence>Foo foo</sentence>
    </root>

尽管如此,我知道我的函数为什么要这样做,但我就是不知道如何复制元素并为它们注入新内容。我知道上下文项存在问题,但我尝试了很多其他方法,但对我没有任何作用。

另一方面,使用匹配//text() 的模板可以正常工作。但要求是使用函数(因为我正在研究多相变换并且我想使用代表每个步骤的函数)。我想知道这个问题有解决方案吗?我错过了一些基本的东西吗?

【问题讨论】:

    标签: xml xslt-2.0


    【解决方案1】:

    如果您一次只需要匹配一个文本节点,那么执行此操作的方法是使用模板规则对树进行递归下降,并使用元素的身份模板和进行分析的模板- 文本节点的字符串。使用一种模式将 this 与其他处理逻辑分开,并从指定此模式的函数中调用 apply-templates,因此模板的使用完全隐藏在函数的实现中。

    【讨论】:

      【解决方案2】:

      这是我对 Michael Kay (+1) 建议的解释的说明...

      XSLT 2.0

      <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:my="my" exclude-result-prefixes="my">
          <xsl:output indent="yes"/>
          <xsl:strip-space elements="*"/>
      
          <xsl:template match="@*|node()" mode="#all" priority="-1">
              <xsl:copy>
                  <xsl:apply-templates select="@*|node()" mode="#current"/>
              </xsl:copy>
          </xsl:template>
      
          <xsl:variable name="var">
              <root>
                  <sentence>Hello world</sentence>
                  <sentence>Foo foo</sentence>
              </root>
          </xsl:variable>
      
          <xsl:function name="my:parse">
              <xsl:param name="input"/>
              <xsl:apply-templates select="$input" mode="markup-step"/>
          </xsl:function>
      
          <xsl:template match="/*">
              <xsl:copy-of select="my:parse($var)"/>
          </xsl:template>
      
          <xsl:template match="text()" mode="markup-step">
              <xsl:analyze-string select="." regex="world">
                  <xsl:matching-substring>
                      <match><xsl:copy-of select="."/></match>
                  </xsl:matching-substring>
                  <xsl:non-matching-substring>
                      <xsl:copy-of select="."/>
                  </xsl:non-matching-substring>
              </xsl:analyze-string>        
          </xsl:template>
      
      </xsl:stylesheet>
      

      输出(使用任何格式良好的 XML 输入)

      <root>
         <sentence>Hello <match>world</match>
         </sentence>
         <sentence>Foo foo</sentence>
      </root>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-30
        • 2011-12-06
        • 2012-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多