1
votes

I have an XML file what I want to filter by an XML file what I pass as parameter to my XSLT 2.0 file with Saxon CE's setParameter function:

xsltData = Saxon.requestXML("filter.xsl");
xmlData = Saxon.requestXML("xmlfile.xml");
var xsltProcessor = Saxon.newXSLT20Processor(xsltData); 
xsltProcessor.setParameter(null, "src", "filterxml.xml");
var result = xsltProcessor.transformToDocument(xmlData);

Parameter XML File:

<?xml version="1.0" encoding="UTF-8"?>
    <Items>
        <Item SrcName="itemname1" NewName="newitemname1"></Item>
        <Item SrcName="itemname2" NewName="newitemname2"></Item>
        <Item SrcName="itemname3" NewName="newitemname3"></Item>
    </Items>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xpath-default-namespace="http://www.mynamespace"
                xmlns="http://www.mynamespace">

    <xsl:strip-space elements="*" />
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" name="xml" />

    <xsl:param name="src"></xsl:param>
    <xsl:variable name="filter-doc" select="if (doc-available($src)) then doc($src) else ()"/>
    <xsl:variable name="Items" select="$filter-doc/Items"></xsl:variable>
    <xsl:template match="/">
        <xsl:apply-templates select="$Items/Item"/>
    </xsl:template> 
</xsl:stylesheet>

The problem is, that I have an xpath-default-namespace in the XSLT file, with this I can't access $Items/Item. If I add the namespace xmlns="http://www.mynamespace" to the element everything is working fine. Is there a way to make this work without adding the namespace to my parameterxml? I know that in the setParameter function the first parameter is namespace, but even if I set a namespace here nothing changes in the result.

Is there any possibility to add the namespace to $Items with XSLT?

2
Why do you have an an xpath-default-namespace in the XSLT file ? Your stylesheet should work without it.M. Page
Because I have a namespace in my input xmlfile, and if I don't set a namespace it's not working.nh_

2 Answers

4
votes

You can change that setting as needed: <xsl:variable name="Items" xpath-default-namespace="" select="$filter-doc/Items"></xsl:variable>.

2
votes

If you need to refer to both namespaced and non-namespaced nodes in the same XSLT then you probably shouldn't use xpath-default-namespace. Instead, bind a prefix to this namespace:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:my="http://www.mynamespace"
                exclude-result-prefixes="my"
                xmlns="http://www.mynamespace">

Now you can refer to nodes in the http://www.mynamespace namespace using my:elementName and bare unprefixed names will refer to nodes (such as your Items) that are not in a namespace.

While you can use different values for xpath-default-namespace in different parts of the document (the processor will look up the tree and use the value on the nearest ancestor it finds) this is something I would personally avoid as it is prone to break under refactoring - e.g. if you decide to extract some code from inside a template into a callable template or xsl:function and inadvertantly move it outside the scope of an xpath-default-namespace. If you stick to prefixes declared at the top level then it is always clear which namespace you mean in which expression.