这个问题有点复杂,因为有很多移动部件,但我会尝试缩小并仅使用最相关的片段。
我正在研究基于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/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>
我创建了一个解析器,它接受一个DataObject
对象(实际上只是一个其他DataObject
对象的奇特树),并使用树中的数据循环解析文档。文档源路径也存储在树中。
解析器构造函数:
public function __construct(DataObject $dataObject){
$this->_dataObject = $dataObject;
}
公共render
方法,用于将文档作为字符串返回:
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
}
}
最后是私人_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;
}
我知道这是一大块,但如果有问题,那就必须在那里。 问题是XPath查询没有返回任何节点。我已经在文档上完全测试了它,它运行正常。它在给定节点的上下文中找到所有<zuq:data />
元素之外的所有<zuq:region />
元素(在递归中是区域,但我还没有),这将允许解析每个区域单独水平。
当我使用$nodeList = $xpath->query('.//*', $frag);
并循环生成$nodeList
时,它包含所有文档元素,从<html>
到最嵌套。
为什么我的$nodeList = $xpath->query('.//zuq:data[not(ancestor::zuq:region)]', $frag);
查询失败了?我真的希望这很简单,“哦,你只是忘了 _ _。”
事先,我真的很感激任何帮助,如果有更多细节需要,我很乐意提供,请告诉我。
答案 0 :(得分:2)
查询失败了吗?我真的希望如此 这是一个简单的问题,“哦,你只是 忘了__。“
我认为就是这样。使用比'http://localhost/~/zuqml'
$ownerDocument->lookupNamespaceURI('zuq')