XSL 仅将命名空间定义添加到 XML 根



我想使用 XSL 将默认命名空间定义添加到根元素中。然而,问题是,在XSL转换后,子元素具有我需要防止的属性xmlns=''

XML 输入:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog>
      <changeSet author="abc" id="def">
...
    </changeSet>
</databaseChangeLog>

预期的 XML 输出:

<?xml version="1.0" encoding="UTF-8"?><databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">
      <changeSet author="abc" id="def">
...
    </changeSet>
</databaseChangeLog>

我尝试过像这样使用 XSL

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/databaseChangeLog">
        <databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
            xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog 
    http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">
            <xsl:apply-templates select="node()|@*" />
        </databaseChangeLog>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}"> 
            <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"?><databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">
      <changeSet xmlns="" author="abc" id="def">
...
    </changeSet>
</databaseChangeLog>

知道如何解决这个问题吗?

请注意,有一个类似的问题:XSLT xmlns 仅在根目录上,但是在我的情况下,XML 中包含更多元素(只是示例中列出的元素),因此这对我来说不可行。

更改

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

<xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="http://www.liquibase.org/xml/ns/dbchangelog">
        <xsl:apply-templates select="node()|@*" />
    </xsl:element>
</xsl:template>

请记住,使用 XSLT,您不会创建命名空间声明。相反,您创建具有正确扩展名称(命名空间 URI 加本地名称)的元素,序列化程序负责正确获取命名空间声明。所以你希望 changeSet 元素位于命名空间 http://www.liquibase.org/xml/ns/dbchangelog 中,你必须在该命名空间中创建它,你不能只在其父元素上放置默认命名空间声明。如果在与其父级不同的命名空间中创建 changeSet 元素,序列化程序将添加一个命名空间声明以反映您的(明显)意图。

试试这个方式:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/*">
    <databaseChangeLog 
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog 
    http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">
        <xsl:apply-templates select="node()|@*" />
    </databaseChangeLog>
</xsl:template>
<xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="http://www.liquibase.org/xml/ns/dbchangelog"> 
        <xsl:apply-templates select="node()|@*" />
    </xsl:element>
</xsl:template>
<xsl:template match="@*">
    <xsl:attribute name="{local-name()}"> 
        <xsl:value-of select="." /> 
    </xsl:attribute>
</xsl:template>
<xsl:template match="text()|comment()|processing-instruction()" >
    <xsl:copy/>
</xsl:template>
</xsl:stylesheet> 

相关内容

  • 没有找到相关文章

最新更新