Frage Die Safari XSLT-Engine verliert den Namespace für Attribute


Ich habe eine XSLT, die bestimmten Attributen entspricht, und legt sie in einem anderen Namespace ab. Hier ist eine vereinfachte Version:

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

Hier ist eine Beispieleingabe:

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

Und hier ist die erwartete Ausgabe:

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

Dies funktioniert gut in Chrome, Firefox, IE 9 und Android. Auf Safari erhalte ich stattdessen folgende Ausgabe:

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

Beachten Sie, dass der Namespace Erklärungen sind korrekt, aber den Attributen fehlt das gewünschte Namespacepräfix.

All dieser Code ist in a GitHub-Projekt, die von gebaut wird TravisCI und verwendet Soßen Labs um auf verschiedenen Browser / Betriebssystem-Kombinationen zu testen.

Kann ich etwas anders mit meinem XSLT machen, das wäre ein korrekterer Weg dies zu erreichen, der bei allen Engines funktionieren könnte? Oder ist das nur ein Fehler in Safari? Irgendwelche Ideen für Workarounds würden sehr geschätzt werden.


10
2017-10-21 18:21


Ursprung


Antworten:


Ich denke, das ist ein Fehler. Als Umgehung könnte man versuchen, den gewünschten Namespace auch auf dem zu setzen xsl:attribute namespace="urn:test:ns2".


1
2017-10-21 20:02



Ohne gegenteilige Beweise scheint dies ein Fehler in Safari zu sein. Ich habe dies Apple (rdar://23207226), aber bis jetzt nichts von ihnen gehört haben.

Die einzige verfügbare Problemumgehung besteht darin, das XSLT auf einer anderen Engine (Server-Seite oder möglicherweise über eine JavaScript-Engine eines Drittanbieters) auszuführen.


1
2017-11-04 14:55