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

PHP使用XSLT处理TEI XML时XPath无法定位元素问题

解决PHP XSLT处理TEI XML时XPath无法匹配元素的问题

问题场景

在PHP中使用XSLT处理包含异文条目的TEI XML文件时,出现XPath无法识别XML元素的问题:XML内存在大量<app>元素,但PHP处理后输出**"There is no app",而在Oxygen中用Saxon-PE 11.4解析时能正常识别<app>元素并输出"There is an app"**。

示例XML片段

<app>
    <rdg wit="#P1 #P2 #P3"/>
    <rdg wit="#A #B #G #M #V">
        <app>
            <rdg wit="#B #G #M #V" type="order">Sermo septimus
                <app>
                    <rdg wit="#B #M #V">adhuc</rdg>
                    <rdg wit="#G"/>
                </app>
            </rdg>
            <rdg wit="#A" type="order">Septimus adhuc sermo</rdg>
        </app>
        de nomine
        <app>
            <rdg wit="#B #G #M #V"/>
            <rdg wit="#A">Jesu</rdg>
        </app>
        gratioso
        <app>
            <rdg wit="#B #M #V">propter
                <app>
                    <rdg wit="#M #V">tres</rdg>
                    <rdg wit="#B"/>
                </app>
                virtutes theologicas</rdg>
            <rdg wit="#A #G"/>
        </app>
    </rdg>
</app>

原XSLT模板

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml"
  xpath-default-namespace="http://www.tei-c.org/ns/1.0" xmlns:tei="http://www.tei-c.org/ns/1.0"
  exclude-result-prefixes="xsl xs tei #default">
  <xsl:output method="html" encoding="UTF-8" indent="yes"/>

  <xsl:template match="/">
    <div>
<xsl:choose>
        <xsl:when test="//app">There is an app</xsl:when>
        <xsl:otherwise>There is no app</xsl:otherwise>
      </xsl:choose>
    </div>
  </xsl:template>

</xsl:stylesheet>

原PHP处理代码

<?php $XML = new DOMDocument(); 
    $XML->load("une_lecon.xml");
    $_SESSION['strXML'] = $XML->saveXML();
    $xslt = new XSLTProcessor();
    $XSL = new DOMDocument();    
    $XSL->load('une_lecon.xsl', LIBXML_NOCDATA);   
    $xslt->importStylesheet( $XSL );
    $transfo = $xslt->transformToXML($XML);
    echo $transfo;?>

问题原因

PHP使用的libxslt是XSLT 1.0的实现,而xpath-default-namespace是XSLT 2.0及以上版本才支持的属性。libxslt会直接忽略这个属性,导致XPath查询的是无命名空间的<app>元素,但实际TEI XML的元素都属于http://www.tei-c.org/ns/1.0命名空间(完整TEI文件的根元素会声明该命名空间),因此匹配失败。

解决方案

由于XSLT 1.0不支持默认命名空间的XPath查询,需要改用命名空间前缀来明确引用目标元素:

修改后的XSLT模板

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml"
  xmlns:tei="http://www.tei-c.org/ns/1.0"
  exclude-result-prefixes="xsl xs tei">
  <xsl:output method="html" encoding="UTF-8" indent="yes"/>

  <xsl:template match="/">
    <div>
      <xsl:choose>
        <!-- 使用tei前缀匹配命名空间下的app元素 -->
        <xsl:when test="//tei:app">There is an app</xsl:when>
        <xsl:otherwise>There is no app</xsl:otherwise>
      </xsl:choose>
    </div>
  </xsl:template>

</xsl:stylesheet>

额外注意事项

确保你的TEI XML根元素正确声明了TEI命名空间,例如:

<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <!-- 其他内容 -->
</TEI>

这样XML中的<app>等元素才会被归入http://www.tei-c.org/ns/1.0命名空间,XPath中的tei:app才能正确匹配。

内容的提问来源于stack exchange,提问作者Pavel Třiska

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:48:09