代码之家  ›  专栏  ›  技术社区  ›  Flag

XSLT-检查序列的所有节点是否匹配一组值

  •  1
  • Flag  · 技术社区  · 8 年前

    使用XSLT v2.0,如何检查所有选定节点的文本是否与某些参考值匹配?

    例如,我选择所有 H1 节点。我想确保它们都等于“标题”或“标题”。

    我一直在尝试为此创建一个函数:

    <xsl:function name="is-valid" as="xs:boolean">
        <xsl:param name="seq" as="item()*" />
        <xsl:for-each select="$seq">
                <xsl:if test="not(matches(current()/text(),'The title|A heading'))">
                    <!-- ??? -->           
                </xsl:if>
        </xsl:for-each>
    </xsl:function>
    

    我不认为这是XSLT的发展方向,但我不知道如何做到这一点。

    有什么提示吗?

    2 回复  |  直到 8 年前
        1
  •  3
  •   Dimitre Novatchev    8 年前

    只需使用这个简单的XPath表达式-- the double negation law :

    not(h1[not(. = ('The title','A heading'))])
    

    作为演示,给定与@kjhughes的答案相同的XML文档:

    <r>
      <h1>Wrong title</h1>
      <h1>The title</h1>
      <h1>A heading</h1>
    </r>
    

    此XSLT 2.0转换:

    <xsl:stylesheet version="20"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
    
      <xsl:template match="/*">
        <xsl:sequence select="not(h1[not(. = ('The title','A heading'))])"/>
      </xsl:template>
    </xsl:stylesheet>
    

    产生所需的正确结果:

    false
    

    这可以在XPath 1.0中使用,以确定是否设置了节点的所有字符串值 $ns1 是另一个节点集的字符串值 $ns2 :

    not(not($ns1[. = $ns2]))
    

    下面是XSLT 2.0/XPath 2.0解决方案的XPath 1,0/XSLT 1.0等效版本:

    <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
    
     <xsl:param name="pValues">
       <v>The title</v>
       <v>A heading</v>
     </xsl:param>
    
     <xsl:variable name="vValues" select="document('')/*/xsl:param[@name='pValues']/*"/>
    
      <xsl:template match="/*">
        <xsl:value-of select="not(h1[not(. = $vValues)])"/>
      </xsl:template>
    </xsl:stylesheet>
    
        2
  •  2
  •   kjhughes    8 年前

    XSLT 2.0具有 every..satisfies 可以在这里提供帮助的构造:

    <xsl:function name="e:is-valid" as="xs:boolean">
      <xsl:param name="s" as="item()*" />
      <xsl:value-of select="every $i in $s satisfies $i=('The title', 'A heading')"/>
    </xsl:function>
    

    下面是一个完整的示例:

    XML格式

    <?xml version="1.0" encoding="UTF-8"?>
    <r>
      <h1>Wrong title</h1>
      <h1>The title</h1>
      <h1>A heading</h1>
    </r>
    

    XSLT公司

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" 
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:e="http://example.com/f">
    
      <xsl:template match="/">
        <xsl:message>
          <xsl:value-of select="e:is-valid(//h1)"/>
        </xsl:message>
      </xsl:template>
    
      <xsl:function name="e:is-valid" as="xs:boolean">
        <xsl:param name="s" as="item()*" />
        <xsl:value-of select="every $i in $s satisfies $i=('The title','A heading')"/>
      </xsl:function>
    
    </xsl:stylesheet>