user7205862
user7205862

Reputation:

XSLT: Why is only the first path evaluated with XPath?

I want to see (in an if) whether an XPath with a string exists. With "/Dataobjekt/persons/person/role" only the first path is evaluated. Other attempts like "/Dataobjekt/persons//person/role" or "/Dataobjekt/persons//.//role" do not work either. How can I find out whether a role exists under Persons?

(The only thing that works is the direct query "/Dataobjekt/persons/person[3]/role")

XML:

<?xml version="1.0" encoding="UTF-16"?>
<Dataobjekt>
    <persons>
        <person>
            <UUID>1</UUID>
            <role>Manager</role>
        </person>
        <person>
            <UUID>2</UUID>
            <role>Employee</role>
        </person>
        <person>
            <UUID>3</UUID>
            <role>CEO</role>
        </person>
    </persons>
    <info>
        <persons>
            <person>
                <salary>2000</salary>
                <role>Manager</role>
            </person>
            <person>
                <salary>1000</salary>
                <role>Employee B</role>
            </person>
            <person>
                <salary>3000</salary>
                <role>CEO</role>
            </person>
        </persons>
    </info>
</Dataobjekt>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soko="http://soko.net/V3.0/sokoSchema">
    <xsl:template match="/">
        <soko:result xmlns:soko="http://soko.net/V3.0/sokoSchema">
                <soko:foo>
                    <xsl:choose>
                        <xsl:when test="contains(/Dataobjekt/persons/person/role, 'Manager')">
                                    OOOOOOOOKKKKKK
                                </xsl:when>
                        <xsl:otherwise>WWWRRROOOONNNNGGG</xsl:otherwise>
                    </xsl:choose>
                    <xsl:choose>
                        <xsl:when test="contains(/Dataobjekt/persons/person/role, 'CEO')">
                                    OOOOOOOOKKKKKK
                                </xsl:when>
                        <xsl:otherwise>WWWRRROOOONNNNGGG</xsl:otherwise>
                    </xsl:choose>
                </soko:foo>
        </soko:result>
    </xsl:template>
</xsl:stylesheet>

Result:

<?xml version="1.0" encoding="UTF-8"?>
<soko:result xmlns:soko="http://soko.net/V3.0/sokoSchema">
    <soko:foo>
                                    OOOOOOOOKKKKKK
                                WWWRRROOOONNNNGGG</soko:foo>
</soko:result>

Upvotes: 0

Views: 37

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116959

The first argument of the contains() function must be a string. When you supply a node-set instead, it is converted to a string by returning the string-value of the first node in the supplied node-set. This is in XSLT 1.0; in XSLT 2.0+ you will get an error.

To test if there is at least one person whose role contains the string "CEO" try:

<xsl:when test="/Dataobjekt/persons/person[contains(role, 'CEO')]">

Note that this assumes a person has at most one role. Otherwise you would need to do:

<xsl:when test="/Dataobjekt/persons/person/role[contains(., 'CEO')]">

Upvotes: 0

Related Questions