You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化eXist-db中的XSLT转换?大XML页面性能优化

问题描述

我用eXist数据库,通过以下XQL代码调用XSLT把TEI XML渲染成HTML:

xquery version "3.1";

declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace m = "http://www.minorworksoflydgate.net/model";
declare default element namespace "http://www.w3.org/1999/xhtml";

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xhtml";
declare option output:media-type "application/xhtml+xml";
declare option output:omit-xml-declaration "no";
declare option output:html-version "5.0";
declare option output:indent "no";
declare option output:include-content-type "no";

declare variable $exist:root as xs:string := 
    request:get-parameter("exist:root", "xmldb:exist:///db/apps");
declare variable $exist:controller as xs:string := 
    request:get-parameter("exist:controller", "/mwjl-app");


declare variable $text := request:get-data(); (:this variable allows the pipeline to work:)
let $xsl := xs:anyURI($exist:root || $exist:controller || "/data/stylesheets/wrapper.xsl")
return
    transform:transform($text, $xsl, ())

待转换的TEI XML主体是嵌套列表结构:

<list type="index">
    <item n="draft" xml:id="6561"><emph rend="italic">A lamentacioun of our lady Maria</emph>
        <ref target="http://www.dimev.net/record.php?recID=6561">(DIMEV: 6561)</ref> 
    </item>
    <list>
        <item>
            <ref target="/Quis_Dabit/Jesus_College_Q_G_8/Jesus_Q_G_8_f19v.html">Cambridge, Jesus College Q.G.8</ref>
        </item>
        <item><ref
            target="/Quis_Dabit/British_Library_Harley_2251/British_Library_Harley_2251_f42v.html"
            >London, British Library Harley 2251</ref></item>
        <item><ref
            target="/Quis_Dabit/British_Library_Harley_2255/British_Library_Harley_2255_f66v.html"
            >London, British Library Harley 2255</ref></item>
        <item><ref target="/Quis_Dabit/Laud_683/Laud_683_f78r.html">Oxford, Bodleian
            Library Laud misc. 683</ref></item>
        <item><ref target="/Quis_Dabit/St_John_56/St_John_56_73v.html">Oxford, St.
            John's College 56</ref></item>
    </list>
    <item n="draft" xml:id="747"><emph rend="italic">A Mumming at Eltham</emph><ref
        target="http://www.dimev.net/record.php?recID=747"> (DIMEV:
        747)</ref></item>
    <list>
        <item><ref target="/Mumming_Eltham/Trinity_R_3_20/Trinity_R_3_20_f19r.html"
            >Cambridge, Trinity College R.3.20</ref></item>
        <item><ref
            target="/Mumming_Eltham/British_Library_Additional_29729/Add_29729_f135v.html"
            >London, British Library Addit. 29729</ref></item>
    </list>
</list>

当前转换功能正常,但XML行数超过8000时,页面渲染速度明显变慢,远不如直接用Saxon转换的效率。因为是单XML页面,索引优化效果不好。我怀疑问题出在大量list/item组合的迭代处理,但不确定解决方法,想请教:

  1. 如何优化XQL以提升页面渲染速度?
  2. 是否应该放弃使用eXist-db?

补充:相关XSLT代码片段(wrapper.xsl和body.xsl):
wrapper.xsl:

<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:teix="http://www.tei-c.org/ns/Examples" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:rng="http://relaxng.org/ns/structure/1.0" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#default html a fo rng tei teix" version="3.0">

    
    <xsl:include href="header.xsl"/>
    <xsl:include href="body.xsl"/>
</xsl:stylesheet>

body.xsl核心片段:

<xsl:template match="tei:list">
    <xsl:choose>
        <xsl:when test="@rend='ordered'">
            <ol>
                <xsl:apply-templates/>
            </ol>
        </xsl:when>
        <xsl:when test="@type='index'">
            <ul class="index">
                <xsl:apply-templates/>
            </ul>
        </xsl:when>
        <xsl:when test="@type='simple'">
            <ul class="nodisplay">
                <xsl:apply-templates/>
            </ul>
        </xsl:when>
        <xsl:when test="@xml:id='compare'">
            <ul class="nodisplay">
                <xsl:apply-templates/>
            </ul>
        </xsl:when>
        <xsl:when test="@type='bibliography'">
            <ul class="nodisplay bibliography">
                <xsl:apply-templates/>
            </ul>
        </xsl:when>
        <xsl:otherwise>
            <ul>
                <xsl:apply-templates/>
            </ul>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="tei:list[@xml:id = 'bullet_list']/tei:item">
    <li>
        <xsl:attribute name="class">
            <xsl:text>bullet_list</xsl:text>
        </xsl:attribute>
        <xsl:apply-templates/>
    </li>
</xsl:template>


<xsl:template match="tei:item">
    <xsl:choose>
        <xsl:when test="@xml:id">
            <li>
                <a>
                    <xsl:attribute name="name">
                        <xsl:value-of select="@xml:id"/>
                    </xsl:attribute>
                    <xsl:attribute name="class">
                        <xsl:text>anchor</xsl:text>
                    </xsl:attribute>
                    <xsl:apply-templates/>
                </a>
            </li>
        </xsl:when>
        <xsl:otherwise>
            <li>
                <xsl:apply-templates/>
            </li>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

优化建议与决策参考

一、XQL与XSLT层面的优化

1. 重构XSLT模板匹配逻辑

当前tei:list和tei:item模板依赖大量<xsl:choose>分支判断,针对大文档可优化为精准匹配的独立模板,减少运行时条件判断开销:

  • 拆分tei:list模板:
    <!-- 替换原tei:list模板 -->
    <xsl:template match="tei:list[@rend='ordered']">
        <ol><xsl:apply-templates/></ol>
    </xsl:template>
    <xsl:template match="tei:list[@type='index']">
        <ul class="index"><xsl:apply-templates/></ul>
    </xsl:template>
    <xsl:template match="tei:list[@type='simple'] | tei:list[@xml:id='compare']">
        <ul class="nodisplay"><xsl:apply-templates/></ul>
    </xsl:template>
    <xsl:template match="tei:list[@type='bibliography']">
        <ul class="nodisplay bibliography"><xsl:apply-templates/></ul>
    </xsl:template>
    <xsl:template match="tei:list">
        <ul><xsl:apply-templates/></ul>
    </xsl:template>
    
  • 拆分tei:item模板并使用属性值模板简化代码:
    <xsl:template match="tei:item[@xml:id]">
        <li>
            <a name="{@xml:id}" class="anchor">
                <xsl:apply-templates/>
            </a>
        </li>
    </xsl:template>
    <xsl:template match="tei:item">
        <li><xsl:apply-templates/></li>
    </xsl:template>
    
    属性值模板替代<xsl:attribute>,既简化代码也提升处理器执行效率。

2. 优化eXist的XML读取方式

避免用request:get-data()读取原始XML字符串再二次解析,直接从数据库读取已解析的XML节点:

let $text := doc("/db/apps/mwjl-app/data/your-large-tei.xml")

跳过字符串转XML的解析步骤,节省资源开销。

3. 减少序列化冗余

将XQL中的output:omit-xml-declaration改为yes,减少大文档序列化时的额外处理(已设置output:indent="no"可保留)。

二、eXist-db配置优化

1. 调整JVM内存参数

eXist基于JVM运行,大文档处理需要足够堆内存。修改conf.xml中的JVM参数:

<java classname="org.exist.start.Main" fork="true">
    <jvmarg value="-Xms4G"/>
    <jvmarg value="-Xmx8G"/>
</java>

根据服务器配置调整堆大小,避免频繁GC拖慢处理速度。

2. 替换为Saxon作为XSLT处理器

eXist默认内置处理器性能弱于Saxon,可配置使用Saxon对齐本地测试性能:

  • 将Saxon的jar包放入eXist的lib/user目录;
  • 修改conf.xml中的处理器配置:
    <transformer class="net.sf.saxon.TransformerFactoryImpl"/>
    

三、是否放弃eXist-db?

优先尝试上述优化,若仍无法达标再考虑替代方案:

  • 若仅需TEI转HTML且文档静态,可采用静态生成:本地用Saxon批量转换后用普通Web服务器托管,性能最优;
  • 若需动态查询、编辑TEI文档,eXist仍是适配的XML数据库,需确保配置和代码完成针对性优化;
  • 替代选项可考虑BaseX等其他XML数据库,或用Python/Java编写自定义服务结合Saxon与数据库存储。

内容的提问来源于stack exchange,提问作者medievalmatt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:15:40