我想使用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 on root only,但在我的情况下,XML中还包含更多元素(如示例中列出的那些元素),因此对我来说不可行。
答案 0 :(得分:2)
变化
<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>
答案 1 :(得分:2)
请记住,使用XSLT,您不会创建名称空间声明。相反,您使用正确的扩展名称(名称空间URI加本地名称)创建元素,并且序列化程序在获取正确的名称空间声明后进行查找。因此,您希望changeSet元素位于名称空间http://www.liquibase.org/xml/ns/dbchangelog中,您必须在该名称空间中创建它,您不能只在其父元素上放置默认名称空间声明。如果在与其父级不同的命名空间中创建changeSet元素,则序列化程序将添加名称空间声明以反映您的(明显)意图。
答案 2 :(得分:0)
以这种方式尝试:
<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>