Получить xpath из результата поиска определенного шаблона регулярного выражения в кучке xml-файлов

У меня много XML-файлов, и я должен искать в этих файлах строку (подробно, которая будет не слишком сложным регулярным выражением).

С результатами я хочу получить xpath узла, в котором находится строка, то есть:

pattern = /home|house/ files: file1.xml, file2.xml etc 

Результаты:

 "home" in file1.xml, xpath: //root/cars/car[2] "house" in file2.xml, xpath: //root[1]/elemA[2][@attribute1='first'] 

Как я могу достичь этого? Я могу использовать PHP, python, Javascript, VIM-плагин (потому что я уже работал с ними)

В PHP: glob файлы XML, xpath все узлы, preg_match_all их текст и, если совпадения, получить xpath узлов с getNodePath() и вывести его:

 $pattern = '/home|house|guide/iu'; foreach (glob('data/*.xml') as $file) { foreach (simplexml_load_file($file)->xpath('//*') as $node) { if (!preg_match_all($pattern, $node, $matches)) continue; printf( "\"%s\" in %s, xpath: %s\n", implode('", "', $matches[0]), basename($file), dom_import_simplexml($node)->getNodePath() ); } } 

Результат (пример):

 "Guide" in iana-charsets-2013-03-05.xml, xpath: /*/*[7]/*[158]/*[4] "Guide" in iana-charsets-2013-03-05.xml, xpath: /*/*[7]/*[224]/*[2] "Guide" in iana-charsets-2013-03-05.xml, xpath: /*/*[7]/*[224]/*[4] "guide" in rdf-dmoz.xml, xpath: /*/*[4]/d:Description "guide" in rdf-dmoz.xml, xpath: /*/*[5]/d:Description 

Хороший вопрос кстати.

Поиск:

  //*[contains('home') or contains('house')] 

В PHP:

Используйте DOMDocument & DOMXPath, а затем просто вызовите DOMNode::getNodePath() в результате совпадений.

Если вам действительно нужно регулярное выражение вместо этих совпадений раньше, то в DOMDocument от php есть только функции XPATH 1.0, но вы можете добавить функциональность DOMXPath, добавив определенную пользователем функцию с помощью DOMXPath::registerPhpFunctions

Взрыв чего-то быстро, без большой обработки ошибок:

 function xpathregexmatch($nodelist,$regex){ foreach($nodelist as $node){ if( $node instanceof DOMText && preg_match($regex,$node->nodeValue)) return true; } return false; } foreach(glob('*.xml') as $file){ $d = new DOMDocument(); $d->load($file); $x = new DOMXPath($d); $x->registerNamespace("php", "http://php.net/xpath"); $x->registerPHPFunctions('xpathregexmatch'); $matches = $x->query('//*[php:function("xpathregexmatch",text(),"/house|home/")]'); if($matches->length){ foreach($matches as $node){ echo $file. ':'.$node->getNodePath().PHP_EOL; } } } 

php simplexml:

 $xml=simplexml_load_string("file1.xml"); foreach ($xml->cars->car[2] as $car) { // do sth with $car } 

Побольше, уточните свой вопрос, пожалуйста.