PHP / ncx (epub) 上的 xPath 查询失败

PHP / xPath Query on ncx (epub) fails

我无法在 this one :

等文件上使用 xPath 检索结果
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
   <head>
       <meta name="dtb:uid" content="RT8513Z9UM0NLKLF8QX9QDJ3E6ZFL2"/>
       <meta name="dtb:depth" content="3"/>
   </head>
   <docTitle>
       <text>Document Title</text>
   </docTitle>
   <navMap>
       <navPoint id="navPoint-1" playOrder="1">
           <navLabel>
               <text>Section with no subsection</text>
           </navLabel>
           <content src="text/content001.xhtml"/>
       </navPoint>
       <navPoint id="navPoint-2" playOrder="2">
           <navLabel>
               <text>TOC entry name Section title
               </text>
           </navLabel>
           <content src="text/content001.xhtml#heading_id_3"/>
           <navPoint id="navPoint-3" playOrder="3">
               <navLabel>
                   <text>Section entry name.</text>
               </navLabel>
               <content src="text/content002.xhtml"/>
           </navPoint>
           <navPoint id="navPoint-4" playOrder="4">
               <navLabel>
                   <text>Introduction.</text>
               </navLabel>
           </navPoint>
       </navPoint>
   </navMap>
</ncx>

执行以下代码:

$ncx = new DOMDocument();
$ncx->preserveWhiteSpace = false;
$ncx->load('/path/to/file');

$xpath = new DOMXPath( $ncx );

$query1 = 'namespace::*';
$result = $xpath->query( $query1 );
echo $result->length . PHP_EOL;

$query2 = '/ncx/navMap/navLabel/text[. = "Introduction."]';
$result = $xpath->query( $query2 );
echo $result->length . PHP_EOL;

$head = $ncx->getElementsbyTagName('head')->item(0);

$query3 = 'head/meta[@name="dtb:depth"]';
$result = $xpath->query( $query3, $head );
echo $result->length . PHP_EOL;

$query4 = 'meta[@name="dtb:depth"]';
$result = $xpath->query( $query4, $head );
echo $result->length . PHP_EOL;

只有 $query1 产生有效结果。 谁能指出错误在哪里?

谢谢

核心问题是您的 XPath 没有考虑 XML 命名空间。您的 XML 在此处定义了默认命名空间:

<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">

因此 ncx 元素及其没有前缀的后代位于该默认命名空间中。要查询默认命名空间中的元素,您需要将前缀映射到命名空间并在 XPath 中使用该前缀,例如:

//map prefix "d" to the default namespace uri
$xpath->registerNamespace("d", "http://www.daisy.org/z3986/2005/ncx/");
.....
$head = $ncx->getElementsbyTagName('head')->item(0);
.....
//use the registered prefix properly in the XPath
$query4 = 'd:meta[@name="dtb:depth"]';
$result = $xpath->query( $query4, $head );
echo $result->length . PHP_EOL;

eval.in demo

输出:

1

除了上面解释的命名空间问题,您需要重新检查您的 XPath 即 $query2,确保它与 XML.[=17 中目标元素的位置完全对应=]