PHP无法使用XSLT样式表导航TEI XML

trnvg8h3  于 2023-05-27  发布在  PHP
关注(0)|答案(1)|浏览(131)

当我使用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的。也许我使用了错误的命名空间定义?

idfiyjo8

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中使用这个:

<?php

$XML = new DOMDocument();
$XML->loadXML(getXMLString());
$XSL = new DOMDocument();
$XSL->loadXML(getXSLString());

$xslt = new XSLTProcessor();
$xslt->importStylesheet($XSL);
echo $xslt->transformToXML($XML);

function getXMLString() {
// Note: Added namespace definition
return <<<'XML'
<app xmlns="http://www.tei-c.org/ns/1.0">
  <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>
XML;
}

function getXSLString() {
return <<<'XML'
<?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 #default">
  
  <xsl:output method="html" encoding="UTF-8" indent="yes"/>

  <xsl:template match="/">
    <div>
      <xsl:choose>
        <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>
XML;
}

输出:

<div xmlns="http://www.w3.org/1999/xhtml">There is an app</div>

相关问题