Toad
Toad

Reputation: 388

XSLT 2 select XPath returning boolean instead of node

I've been fighting this one for ages and just cannot find an answer. Files are plain text, I'm 'executing' the process in MS XmlNotePad

I'm selecting a node with XPath from an external file, but, when I try to output xsl:value-of, all I get is "true", telling me the node exists, but not the node itself.

The question is, why is my variable containing a boolean instead of the node? I've also tried not using a var, instead just putting the path in the select instead, I get the same output "true".

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="2.0">
  <xsl:param name="filename" select="'Elements.xml'"/>
  <xsl:param name="ele" select="document($filename)"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- find an element by id
  1. replace content inside element with value from xml filename
  2. add an element value  -->
  <xsl:template match="@*|node()">
    <!-- get element id attribute value -->      
     <xsl:copy select=".">
     <xsl:variable name="thisid" select="current()/@id"/>
     <xsl:variable name="eleNode" select="$ele//@id=$thisid"/>
     <xsl:value-of select="$thisid"/>
    <!--<xsl:attribute name="style"><xsl:value-of select="document('Elements.xml')*//@id=$thisid/@style"/></xsl:attribute>-->
    <xsl:choose>
        <xsl:when test="$eleNode">
            <xsl:value-of select="$eleNode"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:otherwise>
    </xsl:choose >
     </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 1

Views: 749

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167506

Well, $ele//@id=$thisid is a comparison expression that gives a boolean result. If you want to select elements with a certain id attribute then use $ele//*[@id = $thisid], if you want to select id attributes then use $ele//@id[. = $thisid].

In general, if you really use an XSLT 2 processor, it might be easier to set up a key <xsl:key name="id" match="*" use="@id"/> and simply check for the referenced node inside of the template match e.g.

<xsl:template match="*[@id and key('id', @id, $ele)]">
  <xsl:copy>
    <xsl:value-of select="key('id', @id, $ele)"/>
  </xsl:copy>
</xsl:template>

would replace the contents of any element for which the other documents contains an element of the same id with the contents of that referenced element.

Upvotes: 2

Related Questions