niCad
niCad

Reputation: 92

element found in xpath under relative path and absolute path up to 2nd child

sorry if I'm very noob to this. I had just started xforms and xslt after a few days and now I cannot get over the xform xpath. I am trying to convert this to html and retrieve default data values with this block to search for the data element first

<xsl:if test="not(/h:html/h:head/model/instance/data)">
        no data found
    </xsl:if>

it prints the 'no data found', but then if I put this to search the said element child after child starting from h:head, it says it is found

<xsl:for-each select="/h:html/h:head/*">
    <xsl:if test="name(.) = 'model'">
        model/
        <xsl:for-each  select="./node()">           
            <xsl:if test="name(.) = 'instance'">
                instance/
                <xsl:for-each  select="./node()">
                    <xsl:if test="name(.) = 'data'">
                    data/ found!
                    </xsl:if>
                </xsl:for-each >
            </xsl:if>
        </xsl:for-each >
    </xsl:if>
</xsl:for-each>

My xform looks like this

<?xml-stylesheet type="text/xsl" href="display.xsl"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jr="http://openrosa.org/javarosa">
  <h:head>
    <h:title><![CDATA[Form Title]]></h:title>
    <model>
      <instance>
        <data>
          <start/>
          <end/>
          <today/>
          <phonenumber/>
          <mobilekey/>
          <projectkey/>
...
      </data>
      </instance>
      <itext> ...</itext>
...<bind> s..
</model>
</h:head>
  <h:body>

Based on my xform, data should be at /h:html/h:head/model/instance/data right? I am viewing these on Firefox 29.0.1

Upvotes: 0

Views: 1043

Answers (1)

Joel M. Lamsen
Joel M. Lamsen

Reputation: 7173

It is because you have a default namespace xmlns="http://www.w3.org/2002/xforms"

You xslt:

<xsl:if test="not(/h:html/h:head/model/instance/data)">
    no data found
</xsl:if>

will print no data found because the xpath looks for model/instance/data in a no-namespace node.

To access them properly, you need to declare the default namespace in your XSLT:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:h="http://www.w3.org/1999/xhtml"
    xmlns:zzz="http://www.w3.org/2002/xforms">

and change the xpath to:

/h:html/h:head/zzz:model/zzz:instance/zzz:data

Alternatively, you can use the following xpath:

<xsl:if test="not(/h:html/h:head/*[local-name() = 'model']/*[local-name()='instance']/*[local-name()='data'])">
    no data found
</xsl:if>

the local-name() function will access the node name sans the namespace.

Upvotes: 2

Related Questions