UPDATE (破坏者):这个问题已经得到回答(请参阅下面的),它看起来像是JRE中某些版本中包含的XSLT实现中的一个bug (就像它在jdk中工作,但在jre 1.6.0_20-b02上不工作,在1.6.0_31-B05时根本不工作)。我在Oracle站点上记录了一个bug。
我马上就到了,就功能而言,它现在起作用了。但我不满意其中的一些部分,其中一些(我相信)可能会更短。这就是问题..。详情见下文
这是一个输入xml的例子
<?xml version="1.0" encoding="UTF-8"?>
<t1>
<t2 a1="v1">
<ot1 a2="v2" />
<ot2 a3="v3">
<t3 a5="v4">
<ot1 a2="v5" />
</t3>
</ot2>
</t2>
</t1>-这是预期结果xml的一个示例(请参阅下面的xslt文件,以获得关于的线索)。
<?xml version="1.0" encoding="UTF-8"?>
<t1>
<t2 a1="v1">
<gt2 a="ot2" b="gtv1">
<gt1 a="ot1">v2</gt1>
</gt2>
<gt2 a="ot2" b="v3">
<t3 a5="v4">
<gt2 a="ot2" b="gtv1">
<gt1 a="ot1">v5</gt1>
</gt2>
</t3>
</gt2>
</t2>
</t1>--这是我最终得到的xslt (但不太高兴)。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common" version="1.0"
exclude-result-prefixes="exslt">
<xsl:output method="xml" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="ot1|ot2">
<xsl:variable name="thisResult">
<xsl:apply-templates select="." mode="impl" />
</xsl:variable>
<xsl:apply-templates select="exslt:node-set($thisResult)" />
</xsl:template>
<xsl:template match="ot1" mode="impl">
<ot2 a3="gtv1">
<gt1 a="ot1">
<xsl:value-of select="@a2" />
</gt1>
</ot2>
</xsl:template>
<xsl:template match="ot2" mode="impl">
<gt2 a="ot2" b="{@a3}">
<xsl:for-each select="child::*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*|node()" />
</xsl:element>
</xsl:for-each>
</gt2>
</xsl:template>
</xsl:stylesheet>的问题是:如何缩短时间?
<xsl:for-each select="child::*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*|node()" />
</xsl:element>
</xsl:for-each>我尝试了以下方法,但在本例中,部分结果xml将丢失(特别是gt2元素的属性将丢失)
<xsl:copy-of select="node()"/>也试过
<xsl:copy-of select="*"/>没有成功
发布于 2012-03-25 18:27:54
Dimitre展示了另一种策略,但是要在您最初的帖子中回答这个问题,xsl:for-each是(除了这里没有显示的一些命名空间效果之外)相当于一个单独的
<xsl:copy-of select="*"/>如果用这个替换xsl:for-每个输出,则得到相同的输出。
你建议的替换
<xsl:copy-of select="node()"/>几乎相同,但获取用于缩进源的空白节点,因此输出在空白中有所不同。
你说
(特别是gt3元素的属性将丢失)
但是,编码更改不会改变属性,并且示例输入或输出中没有gt3元素?
发布于 2012-03-25 18:09:36
我需要定义xslt转换,它能够执行所谓的“多传递转换”。
这里没有必要使用多通道处理.
这个简短而简单的转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="ot1">
<gt1 a="ot1"><xsl:value-of select="@a2"/></gt1>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="ot2">
<gt2 a="ot2" b="{@a3}"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>在提供的XML文档上应用时
<t1>
<t2 a1="v1">
<ot1 a2="v2" />
<ot2 a3="v3">
<t3 a5="v4">
<ot1 a2="v5" />
</t3>
</ot2>
</t2>
</t1>生成想要的、正确的结果
<t1>
<t2 a1="v1">
<gt1 a="ot1">v2</gt1>
<gt2 a="ot2" b="v3"/>
<t3 a5="v4">
<gt1 a="ot1">v5</gt1>
</t3>
</t2>
</t1>UPDATE:OP更新了他认为需要多通处理的问题--这仍然是不正确的。
这里是这个新问题的一个简短的简单解决方案,同样是在一个简单的中
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="ot1">
<gt2 a="ot2" b="gtv{substring-after(name(), 'ot')}">
<gt1 a="ot1"><xsl:value-of select="@a2"/></gt1>
</gt2>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="ot2">
<gt2 a="ot2" b="{@a3}"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>将此转换应用于新提供的XML源文档时的:。
<t1>
<t2 a1="v1">
<ot1 a2="v2" />
<ot2 a3="v3">
<t3 a5="v4">
<ot1 a2="v5" />
</t3>
</ot2>
</t2>
</t1>再一次想要的,正确的结果产生
<t1>
<t2 a1="v1">
<gt2 a="ot2" b="gtv1">
<gt1 a="ot1">v2</gt1>
</gt2>
<gt2 a="ot2" b="v3"/>
<t3 a5="v4">
<gt2 a="ot2" b="gtv1">
<gt1 a="ot1">v5</gt1>
</gt2>
</t3>
</t2>
</t1>UPDATE2:由于OP要求对他当前的代码进行重构,特别需要更好地表达以下摘录:
这里有一个明显的重构--只需用替换上面的
<xsl:apply-templates/>修改后的,完整的代码变成
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common" version="1.0"
exclude-result-prefixes="exslt">
<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="ot1|ot2">
<xsl:variable name="thisResult">
<xsl:apply-templates select="." mode="impl" />
</xsl:variable>
<xsl:apply-templates select=
"exslt:node-set($thisResult)" />
</xsl:template>
<xsl:template match="ot1" mode="impl">
<ot2 a3="gtv1">
<gt1 a="ot1">
<xsl:value-of select="@a2" />
</gt1>
</ot2>
</xsl:template>
<xsl:template match="ot2" mode="impl">
<gt2 a="ot2" b="{@a3}">
<xsl:apply-templates/>
</gt2>
</xsl:template>
</xsl:stylesheet>,以及当应用于最新提供的源XML文档时
<t1>
<t2 a1="v1">
<ot1 a2="v2" />
<ot2 a3="v3">
<t3 a5="v4">
<ot1 a2="v5" />
</t3>
</ot2>
</t2>
</t1>想要的结果是
<t1>
<t2 a1="v1">
<gt2 a="ot2" b="gtv1">
<gt1 a="ot1">v2</gt1>
</gt2>
<gt2 a="ot2" b="v3">
<t3 a5="v4">
<gt2 a="ot2" b="gtv1">
<gt1 a="ot1">v5</gt1>
</gt2>
</t3>
</gt2>
</t2>
</t1>https://stackoverflow.com/questions/9862437
复制相似问题