我有一些 XML:
<Root>
<Name>Eding</Name>
<Roll>15</Roll>
<xyz:Address>25, Brigton,SA</xyz:Address>
</Root>
此 xml 无效,因为xyz
未定义命名空间。所以,我想使用 xslt 在根目录中添加命名空间。
我怎样才能做到这一点?
XSLT 只会将命名空间格式良好的 XML 作为输入。因此,如果您的输入不是名称空间格式正确的,则无法使用 XSLT 解决问题。
解决此问题的一种方法是使用外部(已解析)通用实体。
您可以使用声明xyz
命名空间前缀的 XML 文档“包装”无效的 XML 文件,然后使用外部实体包含文件的内容。然后转换文件以删除包装的内容并产生所需的输出。
对于此示例,您的示例文件称为fragment.xml
. 我定义了一个指向文件的外部实体,然后在wrapper
元素内部引用它。该wrapper
元素xyz
定义了命名空间前缀:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wrapper [
<!ENTITY otherFile SYSTEM "fragment.xml">
]>
<wrapper xmlns:xyz="http://stackoverflow.com/questions/12024763/how-can-i-add-a-namespace-xmlnsxyz-to-an-xml-document-using-xslt">
&otherFile;
</wrapper>
当被任何 XML 解析器解析时,文档将被“视为”为:
<wrapper xmlns:xyz="http://stackoverflow.com/questions/12024763/how-can-i-add-a-namespace-xmlnsxyz-to-an-xml-document-using-xslt">
<Root>
<Name>Eding</Name>
<Roll>15</Roll>
<xyz:Address>25, Brigton,SA</xyz:Address>
</Root>
</wrapper>
然后,使用带有模板的修改后的身份转换来删除wrapper
元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<!--identity template to copy all content forward by default -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!--remove the "wrapper" element, then process the rest of the content -->
<xsl:template match="/wrapper">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
产生以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:xyz="http://stackoverflow.com/questions/12024763/how-can-i-add-a-namespace-xmlnsxyz-to-an-xml-document-using-xslt">
<Name>Eding</Name>
<Roll>15</Roll>
<xyz:Address>25, Brigton,SA</xyz:Address>
</Root>