SimpleXML 如何获取节点的行号?

SimpleXML how to get line number of a node?

我在 SimpleXML 和 PHP 中使用它:

foreach ($xml->children() as $node) {
    echo $node->attributes('namespace')->id;
}

打印所有节点的 id 属性(使用命名空间)。

但是现在我想知道 $node 在 XML 文件中的行号。

我需要行号,因为我正在分析 XML 文件,并向用户返回可能出现问题的信息以解决这些问题。所以我需要这样说:"Here you have an error at line X"。我确定 XML 文件将采用标准格式,其中包含足够多的换行符以供使用。

DOM 是可能的。 DOMNode 提供函数 getLineNo().

DOM

$xml = <<<'XML'
<foo>
  <bar/>
</foo>
XML;

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);

var_dump(
  $xpath->evaluate('//bar[1]')->item(0)->getLineNo()
);

输出:

int(2)

简单 XML

SimpleXML 基于 DOM,因此您可以将 SimpleXMLElement 个对象转换为 DOMElement 个对象。

$element = new SimpleXMLElement($xml);
$node = dom_import_simplexml($element->bar);
var_dump($node->getLineNo());

是的,大多数时候如果您对 SimpleXML 有疑问,答案是使用 DOM。

XML阅读器

XMLReader 内部有行号,但这里没有直接访问它们的方法。同样,您必须将其转换为 DOMNode。之所以有效,是因为两者都使用 libxml2。这会将节点及其所有后代读入内存,所以要小心。

$reader = new XMLReader();
$reader->open('data://text/xml;base64,'.base64_encode($xml));

while ($reader->read()) {
  if ($reader->nodeType == XMLReader::ELEMENT && $reader->name== 'bar') {
    var_dump($reader->expand()->getLineNo());
  }
}