How do I specify the namespace of an xml file targeted by an xslt?

If I had an XML file that specifies a namespace, such as

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
         version="3.1">
    <enterprise-beans>
        <session>
            <ejb-name>Manager</ejb-name>
            <ejb-class>com.something.ManagerBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
            <ejb-local-ref>
                <ejb-ref-name>Manager</ejb-ref-name>
                <ejb-ref-type>Session</ejb-ref-type>
                <local-home>com.something.ManagerLocalHome</local-home>
                <local>com.something.ManagerLocal</local>
                <ejb-link>Manager</ejb-link>
            </ejb-local-ref>
        </session>
    </enterprise-beans>
</ejb-jar>

And I wanted to extract just the names with an XSLT, for example,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://java.sun.com/xml/ns/javaee"
                version="1.0"
>
    <xsl:output omit-xml-declaration="yes"/>
    <xsl:template match="/ejb-jar/enterprise-beans/session">
        <session>
            <xsl:value-of select="ejb-name"/>
        </session>
    </xsl:template>
</xsl:stylesheet>

What am I missing? This transform seems to work if I remove the source's xmlns - how can I leave it on and still run the transform?

I was expecting something like:

<session>
  Manager
</session>
<session>
  Manager2
</session>
...

(Really just trying to figure out the namespace issue)

1 answer

  • answered 2018-10-11 19:19 Parfait

    Assuming you need return of the ejb-name and ejb-ref-name elements, consider adding a namespace prefix like doc to your XSLT to use as reference to elements. The XPath descendant::* is used to find names however nested from session.

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:doc="http://java.sun.com/xml/ns/javaee"
                    exclude-result-prefixes="doc"
                    version="1.0">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="/doc:ejb-jar/doc:enterprise-beans">
            <session>
                <xsl:apply-templates select="doc:session"/>
            </session>
        </xsl:template>
    
        <xsl:template match="doc:session">
            <name><xsl:value-of select="descendant::doc:ejb-name"/></name>
            <name><xsl:value-of select="descendant::doc:ejb-ref-name"/></name>
        </xsl:template>
    
    </xsl:stylesheet>
    

    Output

    <session>
      <name>Manager</name>
      <name>Manager</name>
    </session>
    

    XSLT Fiddle