XSLT 2 - 将已知的单词列表封装在段落中

XSLT 2 - encapsulate a known list of words in a para

提问人:Binsky 提问时间:10/3/2023 更新时间:10/3/2023 访问量:42

问:

<CanYouSpanMatches>
      <possMatch>
         <pillME>black cat</pillME>
         <pillME>brown dog</pillME>
         <pillME>tree</pillME>
      </possMatch>
      
      <property_description>A black cat was chased around a large tree by a brown dog
      </property_description>
</CanYouSpanMatches>

使用 XSLT 2,如何在 <property_description> 元素中“封装”所有具有跨度的字符串 (possMatch/pillME)?

我已将 XML 生成为变量 $var 1,但很难添加跨度

我认为tokenize()可能会起作用,但黑猫没有明显的分隔符。

我想要的结果是:

  <property_description>A <span>black cat</span> was chased around a large <span>tree</span> by a <span>brown dog</span>
  </property_description>

谢谢!

XSLT XSLT-2.0

评论

0赞 Martin Honnen 10/3/2023
xsl:analyze-string

答:

2赞 Mads Hansen 10/3/2023 #1

您可以使用 xsl:analyze-string 并生成一个带分隔符的正则表达式,其中模板中的每个值都与 using string-join() 匹配。|pillMEproperty_description/text()

xsl:matching-substring是可以用 包装的地方,然后只返回不匹配的值:spanxsl:non-matching-substring

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="/">
      <xsl:apply-templates select="CanYouSpanMatches/property_description"/>
    </xsl:template>

    <xsl:template match="property_description/text()">
      <xsl:analyze-string select="." regex="{string-join(/CanYouSpanMatches/possMatch/pillME, '|')}">
        <xsl:matching-substring>
          <span><xsl:sequence select="."/></span>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
          <xsl:sequence select="."/>
        </xsl:non-matching-substring>
      </xsl:analyze-string>
    </xsl:template>
    
</xsl:stylesheet>

评论

0赞 michael.hor257k 10/3/2023
好主意!我本来打算建议一个递归函数,但这要优雅得多。
1赞 Martin Honnen 10/3/2023
对于提供的示例数据,不需要它,但一般来说,通过 xsltfunctions.com/xsl/functx_escape-for-regex.html 运行术语可能是必要的,例如 .string-join(/CanYouSpanMatches/possMatch/pillME/functc:escape-for-regex(.), '|')
0赞 Binsky 10/3/2023
谢谢Mads,这对我来说真的很有效。我必须承认,我真的不明白它是如何工作的,但它确实如此!我会把它放到我的工具箱中,以备将来使用。请问一个后续问题。如果这是列表<possMatch> <pillME type=“animal”>black cat</pillME> <pillME type=“animal”>brown dog</pillME> <pillME type=“plant”>tree</pillME> </possMatch>我将无法访问@type,因为 analyse-string 现在正在处理原子类型?有没有办法一次性通过?
0赞 Mads Hansen 10/3/2023
与使用 XPath 从 生成正则表达式的方式类似,您可以使用 中的匹配值再次将 XPath 替换为该值并选择其属性。`pillMExsl:matching-substringpillME