我有2个示例xml文件
<?xml version="1.0" encoding="UTF-8"?>
<foobar>
<foo>ONE</foo>
<bar>a</bar>
</foobar>
<?xml version="1.0" encoding="UTF-8"?>
<foobar>
<foo>ONE</foo>
<foo>two</foo>
<bar>a</bar>
</foobar>
第一个xml的所需输出与输入相同。 第二个xml示例是
<foobar>
<s>
<s>
<foo>ONE</foo>
<foo>two<foo>
</s>
<s>
<bar>a</bar>
</s>
</s>
</foobar>
我有一个xslt文件,它将元素序列放在&#34; s&#34;否则输出相同的xml文件。
我的xslt是 -
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="kGroupLeader" match="*"
use="generate-id(self::*[name() != name(preceding-sibling::*[1])])" />
<xsl:key name ="checkgroup" match="*" use ="self::*[name() = name(preceding-sibling::*[1])]" />
<xsl:template match="*[*]">
<xsl:copy>
<xsl:choose>
<xsl:when test="(key('checkgroup',*))">
<s>
<xsl:for-each select="*[key('kGroupLeader', generate-id())]">
<s>
<xsl:apply-templates select=". | following-sibling::*[
name() = name(current())
and generate-id(current()) = generate-id(
preceding-sibling::*[key('kGroupLeader', generate-id())][1]
)
]" />
</s>
</xsl:for-each>
</s>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
它运行正常。但是它占用了大量内存并且需要花费大量时间来处理大型xml文件。如何提高性能以使我的xslt更快?
答案 0 :(得分:1)
不是使用密钥,另一种方法可能是使用尾递归模板来实现一种&#34; while循环&#34;:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" />
<!-- normal case - identity transform -->
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<!-- for elements that contain adjacent child elements with the same name -->
<xsl:template match="*[*[name() = name(preceding-sibling::*[1])]]">
<xsl:copy>
<!-- wrap contents in an s -->
<s>
<!-- wrap each "run" of consecutive elements with the same name in
another s. We do this by applying "seq" mode templates to
the _first_ element in each run. -->
<xsl:for-each select="*[name() != name(preceding-sibling::*[1])]">
<s><xsl:apply-templates select="." mode="seq" /></s>
</xsl:for-each>
</s>
</xsl:copy>
</xsl:template>
<!-- tail recursion - process self with normal mode templates, then recurse
with this template for next sibling if its name matches mine -->
<xsl:template match="*" mode="seq">
<xsl:apply-templates select="." />
<xsl:apply-templates mode="seq"
select="following-sibling::*[1][name() = name(current())]" />
</xsl:template>
</xsl:stylesheet>
尾递归seq
模式模板实际上是一个循环,用于保持处理元素(使用默认模式模板),直到找到具有不同名称的模板。