Simon
Simon

Reputation: 13

xpath 2.0 selecting elements by attribute

I have been using the following xpath selection in xpath 1.0

<xsl:variable name="id"><xsl:value-of select="./@id" /></xsl:variable>
preceding::exm:messageFlow[@sourceRef = $id]/@targetRef

This worked very well and did exactly what I wanted. However I started using XSLT 2.0 in combination with xPath 2.0 and this does not work anymore (Using the Altova XML processor) I get the following error:

Kann nicht mit Ziel-Typ besetzt werden - Aktuelles Element ist 'sid-B3FD7EE5-043 3-4939-A69F-E74B30FDEB1C' vom Typ xs:untypedAtomic, Typ xs:QName erwartet - =

which translates roughly to:

Cannot be set to target-type - Current element is 'sid-B3FD7EE5-043 3-4939-A69F-E74B30FDEB1C' of type xs:untypedAtomic, type xs:QName expected -

Previously I had a similar problem with this selection:

following::exm:*[exm:incoming = $out] | preceding::exm:*[exm:incoming = $out]

Which again worked in xpath 1.0, but returned a similar error in xPath 2.0 After changing it to

following::exm:*[exm:incoming/text() = $out] | preceding::exm:*[exm:incoming/text() = $out]

It worked in xPath 2.0 as well. I did try doing something similar with the attributes, but it did not work

A small extract of the corresponding XML:

<messageFlow id="sid-80B618A4-E6BF-4438-AF5D-5111AD308FE6" name="" sourceRef="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C" targetRef="sid-6EB2DB76-CC19-48AD-A073-D37C7489F211"/>
<task completionQuantity="1" id="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C" isForCompensation="false" name="call service" startQuantity="1">
     <incoming>sid-2B2BA651-B5BA-4195-9B5B-E6855B1138F4</incoming>
     <incoming>sid-DA4B86E8-C3F2-497C-8C0D-218E95CE9FD1</incoming>
     <outgoing>sid-008948DE-BA59-4897-AC37-2C3AA63DCD82</outgoing>
</task>

Upvotes: 0

Views: 600

Answers (2)

Michael Kay
Michael Kay

Reputation: 163262

I wonder if you have a schema that declares the @id attribute as being of type QName?

With this variable declaration:

<xsl:variable name="id"><xsl:value-of select="./@id" /></xsl:variable>

you are creating a copy of the @id attribute in a new result tree fragment. This is quite unnecessary; your needs would almost certainly be better served by making the variable be simply a reference to the existing attribute, thus:

<xsl:variable name="id" select="@id" />

By making the copy, you are not only writing unnecessary code and incurring unnecessary run-time cost (building a new tree is an expensive operation), but you are also losing the type information. If my conjecture is correct that @id is of type xs:QName, then the variable $id after atomization will be of type xs:untypedAtomic, and comparing it to an xs:QName is likely to fail with a message similar to the one cited.

Upvotes: 1

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

I can't reproduce the problem.

This transformation:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="task">
    <xsl:variable name="id"><xsl:value-of select="./@id" /></xsl:variable>

    <xsl:variable name="vResult"
     select="preceding::messageFlow[@sourceRef = $id]/@targetRef"/>

    <xsl:value-of select="$vResult"/>
 </xsl:template>
</xsl:stylesheet>

when applied on the following document (the provided fragment wrapped in a single top element and stripped off any undefined namespaces):

<t>
    <messageFlow id="sid-80B618A4-E6BF-4438-AF5D-5111AD308FE6"
    name="" sourceRef="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C"
    targetRef="sid-6EB2DB76-CC19-48AD-A073-D37C7489F211"/>
    <task completionQuantity="1" id="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C"
    isForCompensation="false" name="call service" startQuantity="1">
         <incoming>sid-2B2BA651-B5BA-4195-9B5B-E6855B1138F4</incoming>
         <incoming>sid-DA4B86E8-C3F2-497C-8C0D-218E95CE9FD1</incoming>
         <outgoing>sid-008948DE-BA59-4897-AC37-2C3AA63DCD82</outgoing>
    </task>
</t>

when run with both Altova2011 and Saxon 9.1.07, produces the expected, correct result and no error is raised:

sid-6EB2DB76-CC19-48AD-A073-D37C7489F211

Upvotes: 1

Related Questions