从xml的根元素中删除特定的xmlns
我试图对XML文档进行转换,但由于不懂XSLT,因此找不到解决方案。 我有XML文档:从xml的根元素中删除特定的xmlns,xml,xslt,xml-namespaces,Xml,Xslt,Xml Namespaces,我试图对XML文档进行转换,但由于不懂XSLT,因此找不到解决方案。 我有XML文档: <?xml version="1.0" encoding="UTF-8"?> <addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespac
<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='http://whatever/test.xsd'>
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
乔测试员
贝克街5号
我想制作:
<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml">
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
乔测试员
贝克街5号
(假设xsi:noNamespaceSchemaLocation=“…”已经排除了在使用此XSLT之前使用另一个XSLT)
有人能帮我找到解决办法吗
用于消除xsi:noNamespaceSchemaLocation的XSLT是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@xsi:noNamespaceSchemaLocation"/>
</xsl:stylesheet>
请尝试一下:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="xsi"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(. = 'http://www.w3.org/2001/XMLSchema-instance')]" />
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@xsi:noNamespaceSchemaLocation"/>
</xsl:stylesheet>
我有两个选择: XSLT1:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>
产出1:
<?xml version="1.0" encoding="utf-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
乔测试员
贝克街5号
XSLT2:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<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="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>
输出2:
<?xml version="1.0" encoding="utf-8"?>
<addresses>
<address>
<name>Joe Tester</name>
<street>Baker street 5</street>
</address>
</addresses>
乔测试员
贝克街5号
您的问题是,在复制元素节点时,
会隐式复制文档中该点范围内的命名空间节点。尝试为元素节点添加额外模板,以明确排除xsi
命名空间:
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(name() = 'xsi')]" />
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
如果您的xsl:stylesheet
具有xmlns:xsi
,那么您可能还需要按照中的建议添加exclude result prefixes=“xsi”
这应该可以防止xsi名称空间出现在输出中,如果它仅仅是因为它是从输入中复制的,尽管serialiser可以在需要时重新引入它以使输出格式良好(即,如果它需要在该名称空间中输出元素或属性).如何从帖子中指出的“其他XSLT”中删除坏属性?@hd1-user466825想要省略的其余部分是名称空间声明,而不是属性。不幸的是,xmlns:xsi=“…”没有被删除。你说得对。伊恩·罗伯茨的解决方案比我的更接近一步,但看起来他仍然有一个疏忽。请尝试上面修改的方法。我需要从根元素中删除xmlns:xsi=“…”,而不删除xmlns或任何其他xmlns:*。命名空间声明与任何其他属性不同,不会正常处理!您可能不希望声明出现在输出XML中,但XSLT解析器认为它是必要的(因为您可能已经使用了名称空间作为XML中某个元素的前缀!),因此您要么必须从整个XML中删除xmlns,要么只删除一个元素/属性(或多个)它们正在使用名称空间前缀!这几乎起到了作用,但似乎不起作用,因为
self::xsi
是对名为xsi的元素的节点测试<代码>非(name()='xsi')或非(.='http://www.w3.org/2001/XMLSchema-instance)
应该可以完成这项工作。我想你需要一个模板来删除@xsi:noNamespaceSchemaLocation
。。否则,该值在输出中显示为孤立值,因为您使用的是
@InfantProgrammer'Aravind'OP说他们已经在另一个样式表中删除了该值。同意,但可能是他误解了!观察输入和所需的输出XML示例,OP似乎希望使用XSLT摆脱名称空间声明!同样,他也对其他答案发表了评论。@InfantPro'Aravind'是的,我的观点是,删除名称空间的所有用法不足以实现这一点,因为
会复制名称空间节点(即源XML中的作用域声明)及其所复制的元素。XSLT2.0允许
,但在XSLT1.0中这不是一个选项。