Php 为什么这个XPath查询失败?我是不是犯了一个错误?
这个问题有点复杂,因为有很多活动部件,但我将尝试缩小并仅使用最相关的片段 我正在开发一个基于PHP中Php 为什么这个XPath查询失败?我是不是犯了一个错误?,php,dom,xpath,Php,Dom,Xpath,这个问题有点复杂,因为有很多活动部件,但我将尝试缩小并仅使用最相关的片段 我正在开发一个基于PHP中DOM类的XML/XHTML文档解析器,但是使用DOMXPath的部分似乎失败了。鉴于此示例文档: <html xmlns="http://www.w3.org/1999/xhtml" xmlns:zuq="http://localhost/~/zuqml"> <head> <meta http-equiv="Content-Type" content="text/h
DOM
类的XML/XHTML文档解析器,但是使用DOMXPath
的部分似乎失败了。鉴于此示例文档:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:zuq="http://localhost/~/zuqml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<h1 id="pageHeading">
<zuq:data name="pageHeading" />
</h1>
<p id="pageDescription">
<zuq:data name="pageDescription">
<zuq:format type="trim">
<zuq:param name="length">300</zuq:param>
<zuq:param name="append">...</zuq:param>
</zuq:format>
</zuq:data>
</p>
<div id="toolbar">
<zuq:region name="toolbar" />
</div>
<div id="postWrap">
<zuq:region name="post">
<div class="post">
<img height="200" width="200">
<zuq:attr name="src">
./src/<zuq:data name="postImageSrc" />
</zuq:attr>
</img>
<h2><zuq:data name="postHeading" /></h2>
<p>
<zuq:data name="postBody">
<zuq:format type="trim">
<zuq:param name="length">300</zuq:param>
<zuq:param name="append">
<a>
<zuq:attr name="href">
./?postId=<zuq:data name="postId" />
</zuq:attr>
More »
</a>
</zuq:param>
</zuq:format>
</zuq:data>
</p>
</div>
</zuq:region>
</div>
</body>
</html>
调用publicrender
方法以将文档作为字符串返回:
public function render($filename = null){
$document = new DOMDocument;
$frag = $this->_build($document, $this->_dataObject);
if(is_null($filename)){
return $document->saveXML($frag);
}else{
//render to file
}
}
最后是private\u build
方法,在该方法中执行操作的主要部分:
protected function _build(DOMNode $node, DataObject $dataObject){
$ownerDocument = $node instanceof DOMDocument
? $node
: $node->ownerDocument;
$buffer = $ownerDocument->createDocumentFragment();
for($dataIndex = 0; $dataIndex < $dataObject->count(); $dataIndex++){
$frag = $ownerDocument->createDocumentFragment();
if(!$dataObject->hasParent() || ($dataObject->getFilename() != $dataObject->getParent()->getFilename())){
$frag->appendXML(file_get_contents($dataObject->getFilename()));
}else{
foreach($node->childNodes as $child){
$frag->appendChild($child->cloneNode(true));
}
}
$frag->normalize();
$xpath = new DOMXPath($ownerDocument);
$xpath->registerNamespace('zuq', $ownerDocument->lookupNamespaceURI('zuq'));
//THIS IS WHERE THE TROUBLES ARE
$nodeList = $xpath->query('.//zuq:data[not(ancestor::zuq:region)]', $frag);
for($nodeIndex = $nodeList->length - 1; $nodeIndex >= 0; $nodeIndex--){
//PERFORM REPLACEMENTS
}
$buffer->appendChild($frag);
}
return $buffer;
}
protectedfunction\u构建(DOMNode$node,DataObject$DataObject){
$ownerDocument=$DOMDocument的节点实例
?$node
:$node->ownerDocument;
$buffer=$ownerDocument->createDocumentFragment();
对于($dataIndex=0;$dataIndex<$dataObject->count();$dataIndex++){
$frag=$ownerDocument->createDocumentFragment();
如果(!$dataObject->hasParent()| |($dataObject->getFilename()!=$dataObject->getParent()->getFilename())){
$frag->appendXML(文件获取内容($dataObject->getFilename());
}否则{
foreach($node->childNodes作为$child){
$frag->appendChild($child->cloneNode(true));
}
}
$frag->normalize();
$xpath=newdomxpath($ownerDocument);
$xpath->registerNamespace('zuq',$ownerDocument->lookupNamespaceURI('zuq');
//这就是问题所在
$nodeList=$xpath->query(“.//zuq:data[not(祖先::zuq:region)]”,$frag);
对于($nodeIndex=$nodeList->length-1;$nodeIndex>=0;$nodeIndex--){
//更换
}
$buffer->appendChild($frag);
}
返回$buffer;
}
我知道这是相当大的一块,但如果有问题,它必须在那里的某个地方问题是XPath查询没有返回任何节点。我已经在文档上测试过了,效果很好。它在给定节点的上下文中查找任何
元素之外的所有
元素(在递归中是区域,但我还没有),这将允许单独解析每个区域级别。
当我使用$nodeList=$xpath->query(“../*”,$frag)时代码>并循环通过结果的$nodeList
,它包含所有文档元素,从
到最嵌套的元素
为什么我的$nodeList=$xpath->query('.//zuq:data[not(祖先::zuq:region)],$frag)代码>查询失败?我真的希望这只是一个简单的问题,“哦,你只是忘了u_;”
在此之前,我非常感谢任何帮助,如果需要更多细节,我很乐意提供,请告诉我
查询失败了吗?我真的希望
这很简单,“哦,你刚刚
忘了
我想是这样的。使用静态URI'http://localhost/~/zuqml'
优于$ownerDocument->lookupNamespaceURI('zuq')
杰出的Alejandro;这似乎成功了。知道查找失败的原因吗?可能是因为没有实际注册到文档对象的名称空间,因为解析器使用DOMDocumentFragments
来管理文档的区域。我很好奇,因为我一直在我的服务器上移动文件,希望确保文档能够被验证。@TomcatExodus:除了lookupNamespaceURI()
无法正常工作的原因之外,命名空间URI应该是事先知道的静态URI,前缀不应该用作同义词。请记住,您可以为http://localhost/~/zuqml
URI,仍然使用other:data
QName测试选择zuq:data
元素。
protected function _build(DOMNode $node, DataObject $dataObject){
$ownerDocument = $node instanceof DOMDocument
? $node
: $node->ownerDocument;
$buffer = $ownerDocument->createDocumentFragment();
for($dataIndex = 0; $dataIndex < $dataObject->count(); $dataIndex++){
$frag = $ownerDocument->createDocumentFragment();
if(!$dataObject->hasParent() || ($dataObject->getFilename() != $dataObject->getParent()->getFilename())){
$frag->appendXML(file_get_contents($dataObject->getFilename()));
}else{
foreach($node->childNodes as $child){
$frag->appendChild($child->cloneNode(true));
}
}
$frag->normalize();
$xpath = new DOMXPath($ownerDocument);
$xpath->registerNamespace('zuq', $ownerDocument->lookupNamespaceURI('zuq'));
//THIS IS WHERE THE TROUBLES ARE
$nodeList = $xpath->query('.//zuq:data[not(ancestor::zuq:region)]', $frag);
for($nodeIndex = $nodeList->length - 1; $nodeIndex >= 0; $nodeIndex--){
//PERFORM REPLACEMENTS
}
$buffer->appendChild($frag);
}
return $buffer;
}