如何重构这个有//的xslt?

时间:2013-01-31 17:24:47

标签: xml parsing xslt xpath

我正在为xml重构一个xslt,以提高建议here的性能。我对xslt比较新。为什么以下陈述不相同?

Form1中

<xsl:value-of select="//w:style[@w:styleId = $styleName][ancestor::pkg:part/@pkg:name='/word/styles.xml']"/> 

窗体2

<xsl:value-of select="/pkg:package/pkg:part[@pkg:name='/word/styles.xml']/child::w:style[@w:styleId = $styleName]" />

请注意,pkg:package是root,pkg:part是直接子节点。

Form1声明获取w:style元素,其属性等于$styleName,其祖先为pkg:part,属性为@pkg:name='/word/styles.xml'

表单2声明获取w:style元素,其属性等于$styleName pkg:package/pkg:par@pkg:name='/word/styles.xml'

的子元素

我试图改写的实际陈述是这样的:

<xsl:value-of select="//w:style[@w:styleId = $styleName][ancestor::pkg:part/@pkg:name='/word/styles.xml']/w:pPr/w:numPr/w:numId/@w:val"/>

谢谢。

2 个答案:

答案 0 :(得分:2)

你的第二个XPath是在正确的轨道上,但它只匹配w:styles的{​​{1}}的直接子项{pkg:part轴在这里是多余的),我不知道认为他们是。这应该有效:

child::

我认为这是对原始XPath的改进,但它仍然有一个/pkg:package/pkg:part[@pkg:name='/word/styles.xml']//w:style[@w:styleId = $styleName] 。我对wordprocessingML的了解并不是很广泛,但所有// s都是<w:style>元素的子元素,它们都是<w:styles>元素的子元素?如果是这样,这应该工作(为了便于阅读,分为两行):

<pkg:xmlData>

提高性能的另一种可能性是使用密钥。在您的XSLT中,您将定义一个这样的键:

/pkg:package/pkg:part[@pkg:name='/word/styles.xml']
                               /pkg:xmlData/w:styles/w:style[@w:styleId = $styleName]

然后你会像这样访问你想要的风格:

<xsl:key name="kStyle" match="w:style" use="@w:styleId" />

密钥查找通常非常有效,因此第二个选项在性能方面可能更好。

答案 1 :(得分:0)

不要假设以“//”开头的表达式总是不好的。这在过去的日子里确实如此,对于从早期开始没有太多进步的处理器可能仍然如此,但是包括现代版本的Saxon处理器在内的一些处理器“//”非常有效。如果您要进行此类更改,请确保进行测量以显示更改有效。对于这种表达方式,使用密钥更有可能产生积极影响 - 尽管某些处理器甚至会自动为您执行此操作。