我定义了以下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
添加到容器的每个子元素 - 这将是一个reduntant规范,但不应该导致任何问题。
所以这是我想得到的结果:
<?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 =“”?
答案 0 :(得分: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处理器的序列化器已经在父元素或祖先元素上输出,则它们将不会创建命名空间声明。
答案 1 :(得分: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”)