0

我定义了以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="ns0.com" xsi:schemaLocation="ns0.com ns0.xsd">
   <ns1:elementA xmlns:ns1="ns1.com" xsi:schemaLocation="ns1.com ns1.xsd"/>
   <ns2:elementB xmlns:ns2="ns2.com" xsi:schemaLocation="ns2.com ns2.xsd"/>
</ns0:container>

问题是消费应用程序只获取容器内部的元素(不幸的是对容器进行了字符串切割),然后缺少命名空间 xsi 的定义。

我也想xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance 在容器的每个子元素中添加- 这将是一个冗余的规范,但不应该引起任何问题。

所以这是我想要得到的结果:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="container.com" xsi:schemaLocation="ns0.com ns0.xsd">
   <ns1:elementA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="ns1.com" xsi:schemaLocation="ns1.com ns1.xsd" />
   <ns2:elementB xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="ns2.com" xsi:schemaLocation="ns2.com ns2.xsd"/>
</ns0:container>

这是我的 XSLT,我尝试了几个选项,但无法做到:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns0="ns0.com"
    xmlns:ns1="ns1.com"
    xmlns:ns2="ns2.com">
    <xsl:output method="xml" indent="no"/>

    <xsl:template match="ns0:container/*">
        <xsl:copy>
            <!-- Here I want to add the xmlns:xsi as attribute -->
            <xsl:attribute name="xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute>
            <!-- But this does not work - how should I do that? -->
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

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

</xsl:stylesheet>

如何使用 XSLT 向元素添加额外的 xmlns:xsi=""?

4

2 回答 2

1

我建议修复执行字符串处理而不是 XML 处理的代码,因为我认为您无法使用 XSLT 添加名称空间声明。

你所能做的就是

<xsl:template match="ns0:container/*">
    <xsl:copy>
      <xsl:copy-of select="../namespace::*"/>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

但是范围内的命名空间节点无论如何都会被复制,xsl:copy并且在序列化结果树时,如果 XSLT 处理器的序列化程序已经在父元素或祖先元素上输出它们,则它们将不会创建命名空间声明。

于 2013-08-20T09:57:26.003 回答
1

尝试这样的事情

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="ns0.com">
    <xsl:output method="xml" indent="no"/>
    <xsl:template match="ns0:container/*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/*">
        <xsl:element name="{name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="/*/@xsi:*">
        <xsl:attribute name="other:{local-name()}" namespace="{namespace-uri()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

编辑:

您甚至可以将其简化为

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="no"/>
    <xsl:template match="/*">
        <xsl:element name="{name()}" namespace="{namespace-uri()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="/*/@xsi:*">
        <xsl:attribute name="other:{local-name()}" namespace="{namespace-uri()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

我认为在您的 xml 中,您在声明 ns0 的命名空间(xmlns:ns0="container.com")中也有错字。我想你的意思是(xmlns:ns0="ns0.com")

于 2013-08-20T11:25:14.807 回答