是否将xmlns属性合并到根元素?
我正在将一组XML文档从一种格式(不包含名称空间前缀)转换为另一种格式(包含名称空间前缀)。 一切都相对简单,但在XMLNS输出中有点重复。下面是一个例子 (非常简单)输入XML是否将xmlns属性合并到根元素?,xml,xslt,xml-namespaces,Xml,Xslt,Xml Namespaces,我正在将一组XML文档从一种格式(不包含名称空间前缀)转换为另一种格式(包含名称空间前缀)。 一切都相对简单,但在XMLNS输出中有点重复。下面是一个例子 (非常简单)输入XML . 但是,它没有达到预期的效果;我假设我使用它不正确,或者受到xsltproc功能的限制 执行第二次清除XMLNS条目也是一个很好的解决方案 另外,如果它限制了一个解决方案,我认为我的环境将限于XSLT1.0 谢谢你的提示 另一个较小的问题是,是否有更好的方法在输出中获取schemaLocation属性,但这是次要的
. 但是,它没有达到预期的效果;我假设我使用它不正确,或者受到xsltproc功能的限制
执行第二次清除XMLNS条目也是一个很好的解决方案
另外,如果它限制了一个解决方案,我认为我的环境将限于XSLT1.0
谢谢你的提示
另一个较小的问题是,是否有更好的方法在输出中获取schemaLocation属性,但这是次要的。这可能是满足您需求的最短转换:
<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>
<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>
内容
对提供的XML文档执行此转换时:
<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>
<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>
生成所需的正确结果:
<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>
<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>
内容
但是,请注意:将所有名称空间节点放在顶部元素,即使在那里不需要它们,也不建议这样做,因为所有名称空间节点都复制到所有子元素,这会导致大量内存的浪费。问得好,+1。请看我的答案,以更好的写作风格提供一个简短而完整的解决方案,以及一个建议。啊,所以您只需直接插入它们。谢谢你的提示。我能理解你对记忆的担忧。在此阶段,目标是镜像示例文件。当它准备好部署时,切换到一个更高效、更详细的选项就足够容易了。“所有名称空间节点都复制到所有子元素”-因为规范没有指定实现,只指定语义,处理器是否只需要将所有命名空间节点复制到所有子元素?或者用另一种方式表示,所有子节点都有所有祖先的名称空间节点(阴影除外),但这并不意味着在处理器实现中它们必须是单独的副本?@LarsH:名称空间节点“属于”所有子节点,实际上,出于效率原因,它们也被复制。只需对名称空间节点进行计数(),就可以看到有多少名称空间节点。这一结果清楚地表明,当所有名称空间都位于顶部元素时,存在的名称空间节点比名称空间位于它们真正需要的位置时要多。count()
必须显示一个结果,就好像名称空间节点位于所有子体上一样,因为规范在语义上说它们在那里;但这并不意味着特定的XSLT处理器通过制作名称空间节点数据结构的物理副本来实现这一点。我愿意相信你的话,大多数人都是这样做的,但奇怪的是,如果内存成本如此之高,他们会“出于效率原因”这样做,O(n)。。。而查找祖先轴的时间开销是O(log(n))。。。或者更好,如果您有一个智能实现,可以根据需要复制命名空间节点。@LarsH:实现者可能尝试了两种方法,并选择了更高效的实现:)