简体   繁体   中英

Dealing with root node which has a different namespace

XSLT 1.0.

Source XML file:

<?xml version="1.0" encoding="UTF-8"?>
<playlist xmlns="http://xspf.org/ns/0/" version="1">
    <trackList>
        <track>
            <location>1/Kosheen/Independence/01;Addict.flac</location>
            <title>Addict</title>
            <creator>Kosheen</creator>
            <album>Independence</album>
            <duration>286000</duration>
            <image>1/Kosheen/Independence/cover.jpg</image>
        </track>
    </trackList>
</playlist>

XSLT stylesheet file:

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

    <xsl:template match="/playlist/trackList">
        <tracks>
            <xsl:apply-templates select="track"/>
        </tracks>
    </xsl:template>

    <xsl:template match="/playlist/trackList/track">
        <track>
            <xsl:copy-of select="location"/>
            <xsl:copy-of select="title"/>
            <xsl:copy-of select="creator"/>
            <xsl:copy-of select="album"/>
        </track>
    </xsl:template>

</xsl:stylesheet>

Unless I remove the xmlns attribute from the root playlist node the templates in the stylesheet are not applied.

I would like the output XML file to be free of the XSPF namespace.

How should I update the stylesheet to deal with the xspf namespace of the root node?

You need to add a declaration for your namespace and assign a prefix so you can refer to the elements in your source document:

xmlns:ns1="http://xspf.org/ns/0/"

Since your result document is also in the same namespace, you declare it as the default namespace as well:

xmlns="http://xspf.org/ns/0/"

Now you refer to the elements in your source XML with the prefix: ns1:playlist , for example.

Here is your stylesheet with the namespaces added:

<xsl:stylesheet 
    xmlns="http://xspf.org/ns/0/" 
    xmlns:ns1="http://xspf.org/ns/0/"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    exclude-result-prefixes="ns1"
    version="1.0">

    <xsl:output method="xml" encoding="utf-8" omit-xml-declaration="no" indent="no" />

    <xsl:template match="/ns1:playlist/ns1:trackList">
        <tracks>
            <xsl:apply-templates select="ns1:track"/>
        </tracks>
     </xsl:template>
    <xsl:template match="/ns1:playlist/ns1:trackList/ns1:track">
        <track>
            <xsl:copy-of select="ns1:location"/>
            <xsl:copy-of select="ns1:title"/>
            <xsl:copy-of select="ns1:creator"/>
            <xsl:copy-of select="ns1:album"/>
        </track>
    </xsl:template>
</xsl:stylesheet>

Update

If your result must be in no-namespace , you can remove the unprefixed xmlns , but you won't be able to use copy-of (since it copies the full node, including the namespaces - the xmlns declarations will appear in each node). If your child elements have only text, you can replace:

<xsl:copy-of select="ns1:location"/>

with

<location><xsl:value-of select="ns1:location"/></location>

Then you can remove the default xmlns from <xsl:stylesheet> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM