我有一个包含带注释的语音记录的大型xml文档。以下是一个简短的片段。
<?xml version="1.0" encoding="UTF-8"?>
<U>
<A/>
<C type="start" id="cb01s"/>
<P/>
<T>a</T>
<T>woman</T>
<P/>
<T>took</T>
<T>off</T>
<T>the</T>
<T>train</T>
<C type="end" id="cb02e"/>
<P/>
<T>but</T>
<P/>
<F/>
<RT>
<O>
<C type="start" id="cb03s"/>
<T>her</T>
<T>bag</T>
<P/>
<T>are</T>
</O>
<P/>
<E>
<C type="start" id="cb04s"/>
<T>her</T>
<T>bag</T>
<T>are</T>
</E>
</RT>
<P/>
<T>still</T>
<P/>
<T>in</T>
<T>the</T>
<T>train</T>
<C type="end" id="cb05e"/>
<PC>.</PC>
</U>
我需要做的基本任务是获取某些<T>
个节点对之间<C>
个节点的数量。我使用了以下样式表片段来执行此操作(使用一对特定的<C>
节点进行说明)。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="U">
<xsl:variable name="start-node" select="descendant::C[@id = 'cb01s']"/>
<xsl:variable name="end-node" select="descendant::C[@id = 'cb02e']"/>
<xsl:text>Result: </xsl:text>
<xsl:value-of select="count($start-node/following::T[following::C[generate-id(.) = generate-id($end-node)]])"/>
</xsl:template>
</xsl:stylesheet>
这对上面这么短的XML片段工作正常,并给出了正确的结果:Result: 6
。
但是,实际的XML文档包含数万个<C>
个节点甚至更多<T>
个节点。因此,当我尝试在其上运行样式表时,结果会慢慢返回非常。 (完全完成它可能需要数天。)我想问题必须是在<xsl:value-of...
行的每次运行中,处理器(Saxon)正在检查所有<T>
个节点并为{{生成id' 1}}节点倍数倍(即指数),这会减慢一切。
有没有办法在使用generate-id()的同时加快进程?或者我是否需要使用其他方法获取<C>
个节点的数量?
答案 0 :(得分:1)
您不需要generate-id()
只是为了避免匹配起始节点和结束节点之间的<C>
元素。您首先按照<C>
属性匹配id
个元素,我认为没有理由不直接使用它们。例如,
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="U">
<xsl:variable name="start-id" select="cb01s"/>
<xsl:variable name="end-id" select="cb02e"/>
<xsl:text>Result: </xsl:text>
<xsl:value-of select="count(descendant::C[@id = $start-id]/following::T[following::C[@id = $end-id][1]])"/>
</xsl:template>
</xsl:stylesheet>
如果您可以依赖[1]
元素<C>
在文档中是唯一的,则可以通过删除@id
位置谓词来简化该操作。
如果generate-id()
确实是导致性能问题的主要原因,那么完全避免它应该会提供很大的推动力。