2015-04-06 2 views
4

Я использую это в SimpleXML и PHP:SimpleXML Как получить номер строки узла?

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

Это печатает атрибут всех узлов id (с использованием пространства имен).

Но теперь я хочу знать номер строки, что $node находится в XML-файле.

Мне нужен номер строки, потому что я анализирую XML-файл и возвращаю информацию о возможных проблемах для их устранения. Поэтому мне нужно сказать что-то вроде: «Здесь у вас ошибка в строке X». Я уверен, что файл XML будет в стандартном формате, который будет иметь достаточно разрывов строк, чтобы это было полезно.

+2

Зачем вам нужен номер строки? Файл XML может содержать только одну строку, разрывы строк не являются обязательными. Вы можете получить номер записи, используя 'foreach ($ xml-> children() как $ entry => $ node) {' –

+0

@MarkBaker Мне нужен номер строки, потому что я анализирую xml-файл и возвращаюсь к пользователю информацию о возможных проблемах для их решения. Поэтому мне нужно сказать что-то вроде: «Здесь у вас ошибка в строке X». Я уверен, что файл XML будет в стандартном формате, который будет иметь достаточно строк. Спасибо за комментарий. – Ismaestro

+0

Вы «поручитель» неуместны .... нет необходимости в том, чтобы файл XML имел разрывы строк, он не обязан быть каким-либо образом пресечен, и в действительности он часто не преуменьшен. –

ответ

8

Возможно с 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) 

SimpleXML

SimpleXML базируется на DOM, так что вы можете конвертировать SimpleXMLElement объекты DOMElement объектов.

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

И да, большую часть времени, если у вас есть проблемы с SimpleXML, ответ заключается в использовании DOM.

XMLReader

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()); 
    } 
} 
+0

Кажется, что 'XMLReader :: expand :: getLineNo' ограничено 65535. – Drasill

+1

Вот опция LIBXML_PARSEHUGE, которая может использоваться в аргументе' open() 'options. Это изменяет поведение libxml. – ThW

+0

Спасибо за подсказку, но 'LIBXML_PARSEHUGE' не устраняет эту проблему. – Drasill

Смежные вопросы