向XML元素添加额外的xmlns:xsi属性



我定义了以下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复制的,并且在序列化结果树时。

最新更新