membersound
membersound

Reputation: 86915

How to create a boolean variable for if-conditions in XSLT?

I want to iterate a list node to check if every node field matches a global value. The result should be written into a boolean variable. And only if that is true (thus all "Segments" are valid), I want to continue with my logic.

<!-- TODO how to set mytest=true by default? -->
<xsl:variable name="mytest">
    <xsl:for-each select="Segment">
            <xsl:if test=".//SegmentField != $globalValue">
                    <!-- TODO how to set mytest = false? -->
            </xsl:if>
    </xsl:for-each>
</xsl:variable>

<xsl:if test="$mytest">
    <xsl:for-each select="Segment">
        ...creating a csv string
    </xsl:for-each>
</xsl:if>

Or as an alternative, I could check if $mytest is either true or undefined, like (pseudocode):

<xsl:if test="$mytest || not($mytest)">

But how? My goal is to simply check that all SegmentField values inside each Segment are equal.

Example: https://xsltfiddle.liberty-development.net/94rmq6i/1

<OuterElement>
    <SegmentWrapper>
        <Segment>
            <SegmentField>A</SegmentField>
        </Segment>
        <Segment>
            <SegmentField>A</SegmentField>
        </Segment>
    </SegmentWrapper>
    <SegmentWrapper>
        <Segment>
            <SegmentField>B</SegmentField>
        </Segment>
        <Segment>
            <SegmentField>B</SegmentField>
        </Segment>
    </SegmentWrapper>
    <SegmentWrapper>
        <Segment>
            <SegmentField>A</SegmentField>
        </Segment>
        <Segment>
            <SegmentField>B</SegmentField>
        </Segment>
    </SegmentWrapper>
</OuterElement>

XSLT:

  <xsl:template match="OuterElement">
    <xsl:for-each select="SegmentWrapper//Segment">
        <xsl:variable name="mytest" select="not(Segment[SegmentField != SegmentField[1]])" />

        <xsl:if test="$mytest">
            <xsl:value-of select=".//SegmentField" separator=";"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
  </xsl:template>

This should print

A;A
B;B

Upvotes: 0

Views: 2743

Answers (1)

Tim C
Tim C

Reputation: 70648

In this case you should be able to simplify it to just this...

<xsl:variable name="mytest" select="not(Segment[SegmentField != $globalValue])" />

So, the expression Segment[SegmentField != $globalValue]) returns all Segments where the SegmentField does not match the global value. By applying not on this, if there are any elements in the set, then using not will return false, otherwise it returns false.

EDIT: In answer to your edit, if you wanted to check all SegmentField values were the same per SegmentWrapper, you would define your variable like so

<xsl:variable name="mytest" select="not(Segment/SegmentField != Segment/SegmentField)" />

This may seem odd at first glance, as you might think Segment/SegmentField != Segment/SegmentField will always be false. But Segment/SegmentField returns a sequence, and when you a comparison operator on this, it will return true if one of the nodes in the first sequence compares with one in the second sequence.

You don't really need the variable though, you could write this:

<xsl:template match="OuterElement">
  <xsl:for-each select="SegmentWrapper[not(Segment/SegmentField != Segment/SegmentField)]">
    <xsl:value-of select=".//SegmentField" separator=";"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:for-each>
</xsl:template>

Upvotes: 1

Related Questions