xpath-default-namespace:匹配没有命名空间的加载XML的节点

时间:2014-12-01 18:54:46

标签: xml xslt xpath namespaces

我有一个XML文件,我希望通过XML文件过滤我作为参数传递给我的XSLT 2.0文件并使用Saxon CE的setParameter函数:

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);

参数XML文件:

<?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>

问题是,我在XSLT文件中有一个xpath-default-namespace,我无法访问$ Items / Item。 如果我添加名称空间xmlns =&#34; http://www.mynamespace"对元素一切正常。 有没有办法在不将命名空间添加到我的parameterxml的情况下完成这项工作? 我知道在setParameter函数中第一个参数是命名空间,但即使我在这里设置命名空间,结果也没有任何变化。

是否有可能使用XSLT将名称空间添加到$ Items?

2 个答案:

答案 0 :(得分:2)

如果您需要在同一个XSLT中引用命名空间和非命名空间的节点,那么您可能不应该使用xpath-default-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">

现在,您可以使用http://www.mynamespace引用my:elementName命名空间中的节点,并且未加前缀的名称将引用不在命名空间中的节点(例如Items)。

虽然可以在文档的不同部分使用xpath-default-namespace的不同值(处理器将查找树并使用它找到的最近祖先的值)这是某种东西我个人会避免,因为它很容易在重构下破裂 - 例如如果您决定从模板中提取一些代码到可调用模板或xsl:function,并且无意中将其移到xpath-default-namespace的范围之外。如果你坚持在顶级声明的前缀,那么你总是清楚你在哪个表达式中使用哪个命名空间。

答案 1 :(得分:2)

您可以根据需要更改该设置:<xsl:variable name="Items" xpath-default-namespace="" select="$filter-doc/Items"></xsl:variable>