XSLT 1.0: xsl:if test xpath not working for tags without a namespace?

Consider the following XML:

<mergeddocx>

    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

        <w:hyperlink r:id="rId9">
            <w:r>
                <w:t>Hello World!!</w:t>
            </w:r>
        </w:hyperlink>

    </w:document>

    <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
        <Relationship Id="rId9" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="http://x1y1z1.com/" TargetMode="External" />
    </Relationships>

</mergeddocx>

When I try to parse it using the following XSL script:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
exclude-result-prefixes="w r">

<xsl:template match="w:hyperlink">
    <a>
        <xsl:variable name="rId">
            <xsl:value-of select="@r:id"/>
        </xsl:variable>
        <xsl:if test="/mergeddocx/Relationships">
            <xsl:attribute name="href">
                <xsl:value-of select="$rId"/>
            </xsl:attribute>
        </xsl:if>
        <xsl:attribute name="target">
            <xsl:text>_blank</xsl:text>
        </xsl:attribute>
    </a>
</xsl:template>

Instead of getting the expected output of:

<a href="rId9" target="_blank">
</a>

What I am getting is:

<a target="_blank"/>

The xpath in the xsl:if is not accepting that there is a Relationships tag inside the mergeddocx tag. However when I use only /mergeddocx in my test xpath, it works fine.

What am I doing wrong here? How do I include non-namespace containing tags in my xpath?

Thanx in advance!!

Answers


Try it this way:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:rel="http://schemas.openxmlformats.org/package/2006/relationships"
exclude-result-prefixes="w r rel">

<xsl:template match="w:hyperlink">
    <a>
        <xsl:variable name="rId">
            <xsl:value-of select="@r:id"/>
        </xsl:variable>
        <xsl:if test="/mergeddocx/rel:Relationships">
            <xsl:attribute name="href">
                <xsl:value-of select="$rId"/>
            </xsl:attribute>
        </xsl:if>
        <xsl:attribute name="target">
            <xsl:text>_blank</xsl:text>
        </xsl:attribute>
    </a>
</xsl:template>

</xsl:stylesheet>

Note the difference between the xmlns:r and xmlns:rel namespaces.They are not the same.


The elements are in a namespace, you have mistaken the namespace prefix for the namespace.

<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">

The xmlns attribute sets the default namespace to its value. This element and any other element without a namespace prefix will be in this namespace.

So the actual internal address of the node is:

{http://schemas.openxmlformats.org/package/2006/relationships}:Relationships 

That is why you define your own namespace prefixes in the xslt. Add a registration for that namespace to you Xslt:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:rel="http://schemas.openxmlformats.org/package/2006/relationships"
exclude-result-prefixes="w r rel">

Now you can use it:

mergeddocx/rel:Relationships

Unlike element nodes, Xpath has no default namespace. To address an element inside a namespace, you always have to use a namespace prefix.


Need Your Help

Location Button doesn't work GoogleMaps v2

android google-maps geolocation

I'm trying to get my current location with the location button on Google Maps but I have some problems. With the new runtime permissions (API level 23), I don't know if i am doing well or not.

How do I enable sticky load balancing based on session identifiers using apache mod_proxy_balancer

apache proxy httpd.conf mod-proxy load-balancing

Our proxy configuration (in httpd.conf) to send requests to 2 JBoss instances are given below is based on mod_proxy_balancer