0

我正在重构 word xml 的 xslt,以按照此处的建议提高性能。我对 xslt 比较陌生。为什么以下陈述不等价?

表格1

<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 是根, pkg:part 是直接子级。

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

表格 2 状态获得 w:style 元素,其属性等于$styleNamewho are childrenpkg: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"/>

谢谢你。

4

2 回答 2

2

您的第二个 XPath 在正确的轨道上,但它只会匹配(轴在这里是多余的)w:styles的直接子级,我认为它们不是。这应该有效:pkg:partchild::

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

我认为这是对原始 XPath 的改进,但它仍然有一个//。我对wordprocessingML的了解不是很广,但是是不是所有<w:style>的s都是元素的子<w:styles>元素,都是元素的子<pkg:xmlData>元素呢?如果是这样,这应该可以工作(为了便于阅读,分成两行):

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

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

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

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

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

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

于 2013-01-31T17:37:36.357 回答
0

不要假设以“//”开头的表达式总是不好的。这在早期是正确的,对于自早期以来没有太大进步的处理器可能仍然如此,但是包括现代版本的 Saxon 在内的一些处理器非常有效地处理“//”。如果您要进行此类更改,请确保您进行的测量表明更改是有效的。对于这种表达方式,使用键更有可能产生积极的影响——尽管有些处理器甚至会自动为您做到这一点。

于 2013-01-31T22:50:46.283 回答