我正在将一组XML文档从一种格式(不包括名称空间前缀)转换为另一种格式。 一切都相对简单,但在XMLNS输出中有点重复。以下是一个例子。
<?xml version="1.0"?>
<a/>
<!-- xmlns="http://www.w3.org/1999/xhtml" -->
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:a="urn:data.test-a"
xmlns:b="urn:data.test-b"
xmlns:c="urn:data.test-c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:local.test schema/test.xsd"
version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/a">
<xsl:element name="a:test-a">
<!-- attempted fix -->
<xsl:copy-of select="namespace::*"/>
<!-- is there a better way to get this in there? -->
<xsl:attribute name="xsi:schemaLocation">urn:local.test schema/test.xsd</xsl:attribute>
<xsl:element name="b:test-b">
<xsl:element name="c:test-c">content</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0"?>
<a:test-a
xmlns:a="urn:data.test-a"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:local.test schema/test.xsd">
<b:test-b xmlns:b="urn:data.test-b">
<c:test-c xmlns:c="urn:data.test-c">content</c:test-c>
<c:test-c xmlns:c="urn:data.test-c">content</c:test-c>
</b:test-b>
<b:test-b xmlns:b="urn:data.test-b">
<c:test-c xmlns:c="urn:data.test-c">content</c:test-c>
<c:test-c xmlns:c="urn:data.test-c">content</c:test-c>
</b:test-b>
</a:test-a>
<?xml version="1.0"?>
<a:test-a
xmlns:a="urn:data.test-a"
xmlns:b="urn:data.test-b"
xmlns:c="urn:data.test-c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:local.test schema/test.xsd">
<b:test-b>
<c:test-c>content</c:test-c>
<c:test-c>content</c:test-c>
</b:test-b>
<b:test-b>
<c:test-c>content</c:test-c>
<c:test-c>content</c:test-c>
</b:test-b>
</a:test-a>
基本上,我想将命名空间属性合并到根元素中。 我一直在做一些研究,我认为我已经锁定了here。但是,它没有达到预期的效果;我假设我正在使用它不正确或受到xsltproc功能的限制。
执行第二遍以清理XMLNS条目也是一个很好的解决方案。
另外,如果它限制了解决方案,我认为我的环境将仅限于XSLT 1.0。
感谢您的任何提示。
PS。一个较小的问题是,是否有更好的方法在输出中获取schemaLocation属性,但这是次要的。
答案 0 :(得分:2)
这可能是满足您要求的最短转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="urn:data.test-a"
xmlns:b="urn:data.test-b"
xmlns:c="urn:data.test-c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:local.test schema/test.xsd">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="a">
<a:test-a xmlns:a="urn:data.test-a"
xmlns:b="urn:data.test-b"
xmlns:c="urn:data.test-c"
xsi:schemaLocation="urn:local.test schema/test.xsd">
<b:test-b>
<c:test-c>content</c:test-c>
</b:test-b>
</a:test-a>
</xsl:template>
</xsl:stylesheet>
对提供的XML文档执行此转换:
<a/>
产生了想要的正确结果:
<a:test-a xmlns:a="urn:data.test-a"
xmlns:b="urn:data.test-b"
xmlns:c="urn:data.test-c"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:local.test schema/test.xsd">
<b:test-b>
<c:test-c>content</c:test-c>
</b:test-b>
</a:test-a>
但是,请注意:将所有命名空间节点放在顶部元素上,即使它们不需要它们也不是建议的做法,因为所有命名空间节点都被复制到所有后代元素,这导致浪费大量记忆。