我正在为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"/>
谢谢。
答案 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处理器在内的一些处理器“//”非常有效。如果您要进行此类更改,请确保进行测量以显示更改有效。对于这种表达方式,使用密钥更有可能产生积极影响 - 尽管某些处理器甚至会自动为您执行此操作。