当我使用PHP将XSLT模板应用于TEIXML文件时,PHP似乎无法使用X-Path导航XML树,因为它似乎忽略了XML文件中的(所有)元素。
在PHP中,我尝试使用XSLT文件来转换包含不同apparat条目的TEI 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>
我使用以下代码将XSLT应用于PHP中的XML:
<?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;?>
结果HTML包含“没有应用程序”是如果在XML中没有元素,其中实际上有很多。当我在Oxygen中使用解析器Saxon-PE 11.4做同样的事情时,结果如预期的那样包含“There is an app”,所以看起来问题可能是特定于PHP的。也许我使用了错误的命名空间定义?
1条答案
按热度按时间idfiyjo81#
在您的示例XML中,没有定义名称空间,因此XML中的表达式实际上匹配。我设想实际的XML将
http://www.tei-c.org/ns/1.0
定义为默认的元素名称空间。如果我添加命名空间定义,输出是:<div xmlns="http://www.w3.org/1999/xhtml">There is no app</div>
。Xpath 1.0没有默认名称空间的概念,
xpath-default-namespace
在XSL 1.0中不可用。您必须使用前缀/别名来寻址元素。XSLT为名称空间http://www.tei-c.org/ns/1.0
注册前缀tei
。所以你只需要在Xpath表达式//app
→//tei:app
中使用这个:输出: