如果有多个元素

时间:2011-01-10 21:05:32

标签: xml xslt xslt-2.0 xpath-2.0

不知道如何清楚地解释它,所以我只举一个例子: xml文件:

<root>
  <one>
    <a a="x"/>
    <a a="y"/>
  </one>
  <two>
    <a a="x"/>
    <a a="y"/>
  </two>
</root>

这是一个xsl:

    <xsl:template match="/root">
        <xsl:variable name="self" select="."/>

        <xsl:if test="one/a/@a = $self/two/*/a/@a">
          <xsl:text>it works</xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

我只想要if工作......

//修改

解释:

<requirements>
    <bar/><restaurant/>
</requirements>
<offer>
    <bar/></beach><restaurant/><nightclub/>
<offer>

所以我希望'if'检查'offer'的元素是否满足'要求'的所有元素(在这种情况下)

5 个答案:

答案 0 :(得分:1)

这个XSLT 1.0样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kElementByName" match="requirements/*" use="name()"/>
    <xsl:template match="offer[count(*[key('kElementByName',name())])
                               = count(../requirements/*)]">
        <xsl:text>Success!</xsl:text>
    </xsl:template>
</xsl:stylesheet>

使用此输入(格式良好):

<root>
    <requirements>
        <bar/>
        <restaurant/>
    </requirements>
    <offer>
        <bar/>
        <beach/>
        <restaurant/>
        <nightclub/>
    </offer>
</root>

输出:

Success!

注意:使用xsl:key因为函数隐式节点集转换为标量只占用第一个节点。

XPath 2.0表达式:

every $name in /root/requirements/*/name() 
satisfies $name = /root/offer/*/name()

答案 1 :(得分:1)

使用此XPath 2.0表达式

not($requirements[not(name()=$offer/name())])

<强>,其中

$requirements/*/requirements/*

$offer/*/offer/*

,这些是根据下面的XML文档进行评估的(基本上是提供的非格式良好的XML格式良好的XML文档):

<t>
    <requirements>
        <bar/>
        <restaurant/>
    </requirements>
    <offer>
        <baz/>
        <beach/>
        <restaurant/>
        <nightclub/>
    </offer>
</t>

针对您的初始问题的相同技巧:

not(/*/one/a[not(@a = /*/two/a/@a)])

请注意,以上是一个单一的XPath 1.0解决方案:)

答案 2 :(得分:0)

也许这个?

<xsl:template match="/root">
    <xsl:variable name="self" select="."/>
    <xsl:variable name="aKey" select="one/a/@a"/>

    <xsl:if test="$self/two/*/a[@a=$aKey]">
      <xsl:text>it works</xsl:text>
    </xsl:if>
</xsl:template>

答案 3 :(得分:0)

修改

XSLT 1.0解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>

<xsl:variable name="validTest">
    <xsl:for-each select="/*/requirements/*">
        <xsl:value-of select="concat(name(),'+')"/>
    </xsl:for-each>
</xsl:variable>

<xsl:template match="offer">
    <xsl:if test="count(/*/requirements/*) = count(*[
                                    contains($validTest,
                                        concat(name(),'+')
                                        )
                                    ])">
        <xsl:value-of select="concat('#', @id, ' is a valid offer!&#xa;')"/>
    </xsl:if>
</xsl:template>
</xsl:stylesheet>

应用于XML示例:

<root>
  <requirements>
    <bar/><restaurant/>
  </requirements>
  <offer id="1">
    <bar/><beach/><restaurant/><nightclub/>
  </offer>
  <offer id="2">
    <bar/><beach/><nightclub/>
  </offer>
  <offer id="2">
    <beach/><nightclub/><restaurant/>
  </offer>
  <offer id="4">
    <bar/><beach/><restaurant/><nightclub/>
  </offer>
</root>

产生这个结果:

#1 is a valid offer!
#4 is a valid offer!

答案 4 :(得分:0)

也许你正在寻找

  

test =“每个$ x in $ self / one / xxx   $ self / two / yyy满足$ y   满足$ x = $ y“