Safari XSLT引擎在属性上丢失命名空间

时间:2015-10-21 18:21:07

标签: xml xslt safari mobile-safari xslt-1.0

我有一个匹配某些属性的XSLT,并将它们放在不同的命名空间中。这是一个简化版本:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="urn:test:ns1"
    xmlns:ns2="urn:test:ns2">
    <xsl:output method="xml" indent="no" encoding="UTF-8"/>

    <!-- copy all nodes -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*[starts-with(local-name(), 'test-')]">
        <xsl:attribute name="ns2:{substring-after(local-name(), '-')}" namespace="urn:test:ns2">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

以下是一些示例输入:

<?xml version="1.0" encoding="UTF-8" ?>
<hello-world
    xmlns="urn:test:ns1"
    xmlns:ns3="urn:test:ns3"
    rootAttr="stays in implicit namespace"
    ns3:passMe="stays in the ns3 namespace"
    test-someRootAttr="goes into the ns2 namespace, pulls up ns declaration">
    <test
        defaultAttr="stays in implicit namespace"
        test-someAttr="goes into the ns2 namespace"
        ns3:namedAttr="stays in the ns3 namespace">
        Something
    </test>
    <ns3:cat
        defaultAttr="stays in the implicit namespace"
        test-catName="goes into the ns2 namespace"
        ns3:namedAttr="stays in the ns3 namespace">
        a cat
    </ns3:cat>
</hello-world>

这是预期的输出:

<?xml version="1.0" encoding="UTF-8" ?>
<hello-world
    xmlns="urn:test:ns1"
    xmlns:ns2="urn:test:ns2"
    xmlns:ns3="urn:test:ns3"
    rootAttr="stays in implicit namespace"
    ns3:passMe="stays in the ns3 namespace"
    ns2:someRootAttr="goes into the ns2 namespace, pulls up ns declaration">
    <test
        defaultAttr="stays in implicit namespace"
        ns2:someAttr="goes into the ns2 namespace"
        ns3:namedAttr="stays in the ns3 namespace">
        Something
    </test>
    <ns3:cat
        defaultAttr="stays in the implicit namespace"
        ns2:catName="goes into the ns2 namespace"
        ns3:namedAttr="stays in the ns3 namespace">
        a cat
    </ns3:cat>
</hello-world>

这适用于Chrome,Firefox,IE 9+和Android。但是在Safari上,我得到了以下输出:

<?xml version="1.0" encoding="UTF-8" ?>
<hello-world
    xmlns="urn:test:ns1"
    xmlns:ns3="urn:test:ns3"
    xmlns:ns2="urn:test:ns2"
    rootAttr="stays in implicit namespace"
    passMe="stays in the ns3 namespace"
    someRootAttr="goes into the ns2 namespace, pulls up ns declaration">
    <test
        defaultAttr="stays in implicit namespace" 
        someAttr="goes into the ns2 namespace" 
        namedAttr="stays in the ns3 namespace">
        Something
    </test>
    <ns3:cat
        defaultAttr="stays in the implicit namespace" 
        catName="goes into the ns2 namespace" 
        namedAttr="stays in the ns3 namespace">
        a cat
    </ns3:cat>
</hello-world>

请注意,命名空间声明是正确的,但属性缺少所需的命名空间前缀。

所有这些代码都在github project中,由TravisCI构建,并使用Sauce Labs在不同的浏览器/操作系统组合上进行测试。

我可以用我的XSLT做一些不同的事情,这可能是一种更正确的方法,可能适用于所有引擎吗?或者这只是Safari中的一个错误?任何有关变通方法的想法都会非常感激。

2 个答案:

答案 0 :(得分:1)

我认为这是一个错误。作为一种解决方法,您可以尝试在xsl:attribute namespace="urn:test:ns2"上设置所需的命名空间。

答案 1 :(得分:1)

没有任何相反的证据,这似乎是Safari中的一个错误。我已向苹果公司(rdar://23207226)报告了这一情况,但到目前为止还没有从他们那里听到任何消息。

唯一可行的解​​决方法是在其他引擎(服务器端,或者可能通过第三方JavaScript引擎)上运行XSLT。