我定义了以下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="添加到元素中
试试这样的
<?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")中也有一个拼写错误
我建议修复进行字符串处理而不是XML处理的代码,因为我认为您将无法使用XSLT添加命名空间声明。
你所能做的就是
<xsl:template match="ns0:container/*">
<xsl:copy>
<xsl:copy-of select="../namespace::*"/>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
但是作用域内的命名空间节点无论如何都是用CCD_ 2复制的,并且在序列化结果树时。