1

Can anyone explain to me why the following xslt:

<xsl:if test="EventDocument">

Does not pickup this xml tag?

<EventDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.itron.com/ItronInternalXsd/1.0/">

it works when I delete the attributes from the tag, which makes no sense to me.

I.E. the above test passes when i modify the input to be:

<EventDocument>

I'm using xslt 2.0 (saxon parser) Thanks in advance

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183

2 Answers2

2

xmlns is "reserved attribute" - it is definition of mapping of namespace prefix to full node namespace. Covered in details in What does "xmlns" in XML mean?

I.e. actual name of the node in your case is "http://www.itron.com/ItronInternalXsd/1.0/" EventDocument, but you trying to select "" EventDocument (Node with name "EventDocument" and empty namespace).

Depending on your XPath engine you need either

  • pass mapping of your namespace prefixes to namespaces
  • use explicit matching to namespace and node names. *[namespace-uri()="http://www.itron.com/ItronInternalXsd/1.0/" and local-name()=="EventDocument"]
  • cheat and just match node names *[local-name()=="EventDocument"]

(local-name and namespace-uri covered in http://www.w3.org/TR/xpath/#section-Node-Set-Functions).

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
2

By default, unprefixed element names in XPath expressions refer to elements with no namespace, thus an expression EventDocument selects elements with local name "EventDocument" and no namespace. The

<EventDocument ... xmlns="http://www.itron.com/ItronInternalXsd/1.0/">

element does not match this pattern, as it is in the http://www.itron.com/ItronInternalXsd/1.0/ namespace.

You have two choices, either

  1. bind that namespace to a prefix in the stylesheet, then use the prefix in the XPath expression, or
  2. (since you say you are in XSLT 2.0) use xpath-default-namespace

Example of 1

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:itron="http://www.itron.com/ItronInternalXsd/1.0/"
       version="2.0">

  <xsl:template match="itron:example">
    <xsl:if test="itron:EventDocument">....</xsl:if>
  </xsl:template>
</xsl:stylesheet>

Example of 2

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xpath-default-namespace="http://www.itron.com/ItronInternalXsd/1.0/"
       version="2.0">

  <xsl:template match="example">
    <xsl:if test="EventDocument">....</xsl:if>
  </xsl:template>
</xsl:stylesheet>

My personal preference is for option 1, on the "principle of least surprise" basis for anyone who has to maintain the stylesheet in future (including the original author, coming back to the code after a few months break...).

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183