优化 xslt xpath 匹配表达式

Posted

技术标签:

【中文标题】优化 xslt xpath 匹配表达式【英文标题】:Optimize xslt xpath matching expression 【发布时间】:2021-11-08 19:35:30 【问题描述】:

在将 xml 转换为另一种格式时,我的 xpath 表达式评估占用了大量时间。在浏览了网上的几篇文章后,我意识到可能有机会改进我的 xpath 表达式,但我是全新的 xslt。如果有人可以帮助优化以下 xpath 会有所帮助,或者您是否可以确认是否有改进的范围。

此外,xslt 中存在重复的 xpath 模式

<xsl:template
    match="h1:Document/h1:component/h1:Body/h1:component/h1:section[h1:code/@code='1234']">
    <xsl:element name="eSection">
        <xsl:if test="h1:text">
            <xsl:element name="sectionT">
                <xsl:copy-of select="h1:text"
                    copy-namespaces="no" />
            </xsl:element>
        </xsl:if>
        <xsl:for-each select="h1:entry">
            <xsl:element name="sectionE">
                <xsl:copy-of select="." copy-namespaces="no" />
            </xsl:element>
        </xsl:for-each>
    </xsl:element>
</xsl:template>

 <xsl:template
    match="h1:Document/h1:component/h1:Body/h1:component/h1:section[h1:code/@code='6789']">

    <xsl:element name="mSection">
        <xsl:if test="h1:text">
            <xsl:element name="sectionT">
                <xsl:copy-of select="h1:text"
                    copy-namespaces="no" />
            </xsl:element>
        </xsl:if>

        <xsl:for-each select="h1:entry">
            <xsl:element name="sectionE">
                <xsl:copy-of select="." copy-namespaces="no" />
            </xsl:element>
        </xsl:for-each>

    </xsl:element>
</xsl:template>

分析详细信息:

【问题讨论】:

您是否测量并分析了完整的 XSLT 样式表以检查该特定模板是否是性能问题的罪魁祸首? @MartinHonnen 是的,使用氧气进行了分析。 然后向我们展示分析输出的相关详细信息,向我们展示有关输入大小的一些详细信息,性能详细信息,例如完整执行时间,在该特定模板中花费的时间。 我正在使用大约 500KB 的小 xml 进行测试,但在生产中 xml 的大小约为 4 MB,并且有多个这样的文档。我已经添加了分析详细信息。看看吧。 在单个样式表运行期间有多个文档?在这种情况下,您需要显示更多关于您在何处/如何加载/处理它们的上下文。 【参考方案1】:

鉴于h1:Document/h1:component/h1:Body/h1:component/h1:section[h1:code/@code='1234'],尝试使用密钥&lt;xsl:key name="section-by-code" match="h1:Document/h1:component/h1:Body/h1:component/h1:section" use="h1:code/@code"/&gt; 然后

<xsl:template match="key('section-by-code', '1234')">
  <eSection>
    <xsl:where-populated>
      <sectionT>
         <xsl:copy-of select="h1:text"
                    copy-namespaces="no" />
      </sectionT>
    </xsl:where-populated>
    <xsl:apply-templates select="h1:entry"/>
  </eSection>    
</xsl:template>

<xsl:template match="h1:entry">
  <sectionE>
    <xsl:copy-of select="." copy-namespaces="no" />
  </sectionE>
</xsl:template>

【讨论】:

以上是关于优化 xslt xpath 匹配表达式的主要内容,如果未能解决你的问题,请参考以下文章

XSLT XPATH 出错(表达式必须计算为节点集)

使用带有多个表达式的祖先或自我选择 text() XSLT XPATH

XPATH使用

如何使用 XSLT/XPath 生成逗号分隔的列表?

如何在 xpath 表达式中实现具有名称的用户定义函数?

XsltTransform System.Xml.XPath.XPathException:“表达式必须计算为节点集。”