tom
tom

Reputation: 33

if with multiple elements

Don't know how to clearly explain it, so I'll just give an example: xml file:

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

and here's an 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>

I just want the if to work...

//edit

An explanation:

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

so i want the 'if' to check if all (in this case) elements of 'requirements' are satisfied by the elements of 'offer'

Upvotes: 1

Views: 682

Answers (5)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243599

Use this XPath 2.0 expression:

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

where:

$requirements is /*/requirements/*

and

$offer is /*/offer/*

and these are evaluated against the XML document below (essentially the provided non-wellformed XML made well-formed XML document):

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

The same technique for your initial problem:

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

Note that the above is a one-lener XPath 1.0 solution. : )

Upvotes: 1

user357812
user357812

Reputation:

This XSLT 1.0 stylesheet:

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

With this input (well formed):

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

Output:

Success!

Note: The use of xsl:key because functions implicit node set casting to scalar only takes the first node.

XPath 2.0 expression:

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

Upvotes: 1

Flack
Flack

Reputation: 5892

EDIT

XSLT 1.0 Solution:

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

Applied to the XML sample:

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

produces this result:

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

Upvotes: 0

Michael Kay
Michael Kay

Reputation: 163625

Perhaps you're looking for

test="every $x in $self/one/xxx satisfies some $y in $self/two/yyy satisfies $x = $y"

Upvotes: 0

CaffGeek
CaffGeek

Reputation: 22064

Perhaps this?

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

Upvotes: 0

Related Questions