【问题标题】:XSLT: test if sibling matches list of conditionsXSLT:测试兄弟是否匹配条件列表
【发布时间】:2020-02-04 14:48:03
【问题描述】:

我有一个条件列表,我想检查一个元素的直接兄弟是否匹配任何这些条件。

如果这些条件是简单的标签名称,这很容易。

<xsl:param name="tag-list" select="tokenize('img figure table', '\s+')"/>

<xsl:template match="* | text()">
<xsl:variable name="next-name" select="name(following-sibling::*[1])" />
<xsl:if test="$next-name = $tag-list">
<!-- DoSomething -->
</xsl:if>
</xsl:template>

此模板将匹配任何元素或文本节点,如果该节点的紧随其后的兄弟节点是 &lt;img&gt;, &lt;figure&gt; or &lt;table&gt;,则将执行 DoSomething。

但是,我想检查更复杂的条件。当模板与具有特定属性、子项或文本值的同级元素匹配时,我如何才能只做 DoSomething?我更喜欢使用单个 &lt;xsl:if&gt; 来执行此操作,因为此同级条件列表可能会很长。

<xsl:param name="tag-list" select="tokenize('img[@src] figure[text()] table[tbody]', '\s+')"/>

<xsl:template match="* | text()">
<xsl:if test="???">
<!-- DoSomething -->
</xsl:if>
</xsl:template>

【问题讨论】:

  • 不应该简单地将条件放在匹配模式的谓词中吗?任何,因为您使用了 XSLT 3 标记,所以可能有一种使用静态参数和影子属性的方法。你知道它们是如何工作的吗? stackoverflow.com/a/39368038/252228 有一个例子。

标签: xslt xslt-3.0


【解决方案1】:

定义一个代表复杂情况的函数:

<xsl:function name="my:condition" as="xs:boolean">
  <xsl:param name="node" as="node()"/>
  ... your condition goes here ...
</xsl:function>

然后测试是:

<xsl:if test="following-sibling::*[1][my:condition(.)]">...</xsl:if>

如果您想将条件模块化为单独的函数,那么您当然可以这样做:

<xsl:function name="my:condition" as="xs:boolean">
  <xsl:param name="node" as="node()"/>
  <xsl:sequence select="my:first($node) and my:second($node) and..."/>
</xsl:function>

如果你想让逻辑更动态一点,那么条件列表以某种方式动态提供,那么考虑使用高阶函数。

【讨论】:

    【解决方案2】:

    如果您使用 XSLT 3,请考虑是否具有阴影属性的静态参数允许您在样式表编译之前即时构造正确的 XPath 表达式:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:param name="tag-list" static="yes" select="tokenize('img[@src] figure[text()] table[tbody]', '\s+')"/>
    
      <xsl:template match="* | text()">
        <xsl:if _test="{string-join($tag-list ! ('following-sibling::*[1][self::' || . || ']'), ' | ')}">
            <xsl:comment>DoSomething</xsl:comment>
        </xsl:if>
        <xsl:next-match/>
      </xsl:template>
    
      <xsl:mode on-no-match="shallow-copy"/>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/3NSTbf3 转换

    <root>
        <section><span>test</span><img src="foo.jpeg"/></section>
        <section>test<table><tbody>...</tbody></table><span>test</span><figure>...</figure></section>
    </root>
    

    进入

    <root>
        <section><!--DoSomething--><span>test</span><img src="foo.jpeg"/></section>
        <section><!--DoSomething-->test<table><tbody>...</tbody></table><!--DoSomething--><span>test</span><figure>...</figure></section>
    </root>
    

    该示例旨在显示 _test 作为阴影属性的使用,我有意使用了不同的模板内容,因为它似乎更容易显示带有身份转换的代码结果以及输出的注释xsl:if 开始了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多