XSLT,xml到xml无法正确获得名称空间

时间:2018-08-11 04:14:29

标签: xml xslt xml-namespaces

我在将xml转换为另一个xml时遇到了一些麻烦,我不知道如何仅将我的名称空间添加到我的根元素中,它总是将作者名称空间添加到错误的位置

我的起始XML

<?xml version="1.0" encoding="utf-8"?>

<library>
    <authors>
        <author id="a1">
            <name>Bob</name>
            <surname>some surname</surname>
            <born>1939-11-11</born>
        </author>
        <author id="a4">
            <name>Rob</name>
            <surname>surname</surname>
            <born>1973-02-19</born>
        </author>
    </authors>
    <books>
        <book id="b1" author-id="a1">
            <title>Some title</title>
            <published>1392</published>
        </book>
        <book id="b2" author-id="a4">
            <title>Some other title</title>
            <published>1743</published>
        </book>
    </books>
</library>

我希望我的输出看起来像什么

<?xml version="1.0" encoding="utf-8"?>
<books xmlns="http://example.net/books/1.0" 
    xmlns:a="http://example.net/author/1.0">
    <book>
        <a:author>
            <a:name>Bob</a:name>
            <a:surname>some surname</a:surname>
        </a:author>
        <title>Some title</title>
    </book>
    <book>
        <a:author>
            <a:name>Rob</a:name>
            <a:surname>surname</a:surname>
        </a:author>
        <title>Some other title</title>
    </book>
</books>

我现在有什么

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://example.net/books/1.0"
                xmlns:a="http://example.net/author/1.0"
                >
    <xsl:output method="xml" indent="yes" version="1.0"/>
    <xsl:template match="/">
        <xsl:element name="books">
            <xsl:for-each select="library/books/book">
                <xsl:element name="book">
                    <xsl:variable name="authorId" select="@author-id"/>
                    <xsl:element name="a:author">
                        <xsl:element name="a:name">
                            <xsl:value-of select="../../a:authors/a:author[@id=$authorId]/name"/>
                        </xsl:element>
                        <xsl:element name="a:surname">
                            <xsl:value-of select="../../a:authors/a:author[@id=$authorId]/surname"/>
                        </xsl:element>
                    </xsl:element>
                    <xsl:element name="title">
                        <xsl:value-of select="title"/>
                    </xsl:element>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

它给我我的命名空间使用错误的元素(我需要将它放在书中)

<?xml version="1.0" encoding="utf-8"?>
<books xmlns="http://example.net/books/1.0">
    <book>
        <a:author xmlns:a="http://example.net/author/1.0">
            <a:name>Bob</a:name>
            <a:surname>some surname</a:surname>
        </a:author>
        <title>Some title</title>
    </book>
    <book>
        <a:author>
            <a:name>Rob</a:name>
            <a:surname>surname</a:surname>
        </a:author>
        <title>Some other title</title>
    </book>
</books>

1 个答案:

答案 0 :(得分:0)

在这种情况下,您在声明xmlns:a命名空间的位置上并没有什么不同,但是如果您确实确实希望在根元素上声明一次,可以尝试将声明添加到该名称空间的创建中根元素

<books xmlns:a="http://example.net/author/1.0">

尝试使用此XSLT(我也简化了此操作,可以直接写出元素名称,而不是使用xsl:element并使用键来查找作者)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://example.net/books/1.0">
    <xsl:output method="xml" indent="yes" version="1.0"/>

    <xsl:key name="authors" match="author" use="@id" />

    <xsl:template match="/">
        <books xmlns:a="http://example.net/author/1.0">
            <xsl:for-each select="library/books/book">
                <book>
                    <xsl:variable name="author" select="key('authors', @author-id)"/>
                    <a:author>
                        <a:name>
                            <xsl:value-of select="$author/name"/>
                        </a:name>
                        <a:surname>
                            <xsl:value-of select="$author/surname"/>
                        </a:surname>
                    </a:author>
                    <title>
                        <xsl:value-of select="title"/>
                    </title>
                </book>
            </xsl:for-each>
        </books>
    </xsl:template>
</xsl:stylesheet>