2014-10-01 97 views
0
解析文本节点在XML

比方说,我有这个临时文件:如何使用XSLT 2.0功能

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

我使用分析字符串中找到“世界”的字符串,将元素包裹叫<match>

<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()的模板工作正常。但是要求是使用函数(因为我正在处理多相变换,并且我想使用代表每个步骤的函数)。我不知道是否有解决这个问题?我错过了一些基本的东西?

回答

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> 
+0

我将此标记为已接受的答案,但是谢谢你们两位! – Allwe 2014-10-11 22:23:57

3

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