Intereting Posts
$ var :: staticfunction () ОК, но $ this-> var :: staticfunction () NOT. В чем смысл? Вопрос о включении html-страницы в PHP Замена ключевых слов в тексте с помощью php & mysql PHP Script для перенаправления на URL-адрес Как сортировать по двум значениям, а затем поле ASC в массиве с использованием usort () в PHP? Условия проектирования MVC: CRUDing унаследованные модели Разверните Laravel 5.1 на облачном хостинге Загрузка файлов в IE6 «Неустранимая ошибка: не удается переопределить класс» … но класс не был объявлен Слова после вопросительного знака отсутствуют при нажатии кнопки, чтобы открыть ссылку php artisan оптимизирует время только на установке композитора Почему я получаю сообщение об ошибке «не удалось открыть поток» при отправке данных из контактной формы? Фильтр MySQL для многих-ко-многим PHP Несколько одновременных запросов данных Как показать цену продажи или обычную цену woocommerce, если нет цены продажи

PHP XPath. Преобразование сложных XML в массив

Через три дня, пытаясь разобраться в этом, я должен отказаться. Это выдержка из огромного XML, экспортированного из дБ итальянских законов. Я хотел бы преобразовать этот XML в массив PHP, поскольку цель состоит в том, чтобы использовать массив для создания форматированного документа Word с использованием PHP-класса в качестве PHP2RTF.

<CodiceRegionale> <sommario> <elementoCapitolo>CAP a1</elementoCapitolo> <elementoCapitoloDescr> </elementoCapitoloDescr> <elementoSommarioLegge> <elementoTesto>1.1 Legge</elementoTesto> </elementoSommarioLegge> </sommario> <LeggeRegionale id="urn:nir:2014-12-12;26" xmlns="http://www.normeinrete.it/nir/2.1/"> <elementoSommario xmlns=""> <elementoCapitolo>CAP a1</elementoCapitolo> <elementoCapitoloDescr> </elementoCapitoloDescr> <elementoSettore /> <elementoSettoreDescr /> </elementoSommario> <intestazione>Lex 12 2014, n. 26.</intestazione> <articolato> <articolo id="art41" xmlns="http://www.normeinrete.it/nir/2.1/"> <num>Art. 41</num> <rubrica>(Riforma della finanza locale)</rubrica> <comma id="art41-com1"> <num>1. </num> <alinea>Al fine di supportare...</alinea> <el id="art41-com1-let_a"> <num>a) </num> <corpo>definizione di...</corpo> </el> <el id="art41-com1-let_b"> <num>b) </num> <corpo>coordinamento della...</corpo> </el> <el id="art41-com1-let_c"> <num>c) </num> <corpo>definizione delle...</corpo> </el> <el id="art41-com1-let_d"> <num>d) </num> <corpo>la disciplina...</corpo> </el> </comma> <comma id="art41-com2"> <num>2. </num> <alinea>La revisione di...</alinea> <el id="art41-com2-let_a"> <num>a) </num> <corpo> razionalizzazione e... <rif xlink:href="urn:nir:stato:legge:2010-12-13;220#art1-com154" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink">articolo 1, comma 154, della legge 13 dicembre 2010, n. 220</rif> (Legge di stabilità 2011); </corpo> </el> <el id="art41-com2-let_b"> <num>b) </num> <corpo> applicazione dei... <rif xlink:href="urn:nir:stato:costituzione:1947-12-27#art119" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink">articolo 119 della Costituzione</rif> , nonché del principio... </corpo> </el> <el id="art41-com2-let_c"> <num>c) </num> <corpo>valorizzazione...</corpo> </el> <el id="art41-com2-let_d"> <num>d) </num> <corpo>previsione di...</corpo> </el> <el id="art41-com2-let_e"> <num>e) </num> <corpo>valorizzazione del...</corpo> </el> <el id="art41-com2-let_f"> <num>f) </num> <corpo>previsione di...</corpo> </el> </comma> <comma id="art41-com3"> <num>3. </num> <corpo>La revisione normativa...</corpo> </comma> <comma id="art41-com4"> <num>4. </num> <corpo>I disegni di...</corpo> </comma> </articolo> <articolo id="art42" xmlns="http://www.normeinrete.it/nir/2.1/"> <num>Art. 42</num> <rubrica>(Supporto finanziario regionale agli enti locali)</rubrica> <comma id="art42-com1"> <num>1. </num> <corpo>Il supporto...</corpo> </comma> <comma id="art42-com2"> <num>2. </num> <corpo>Per le finalità di...</corpo> </comma> <comma id="art42-com3"> <num>3. </num> <corpo>Gli incentivi regionali...</corpo> </comma> <comma id="art42-com4"> <num>4. </num> <corpo> In attuazione... <rif xlink:href="urn:nir:stato:decreto.legislativo:1997-01-02;9#art9" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink">articolo 9 ...</rif> (Norme di attuazione dello <rif xlink:href="urn:nir:regione.friuli.venezia.giulia:statuto:" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink">statuto</rif> speciale... </corpo> </comma> <comma id="art42-com5"> <num>5. </num> <corpo>Le modalità...</corpo> </comma> </articolo> </articolato> </LeggeRegionale> <LeggeRegionale id="urn:nir:2015-05-22;12" xmlns="http://www.normeinrete.it/nir/2.1/"> <elementoSommario xmlns=""> <elementoCapitolo>CAP a7</elementoCapitolo> <elementoCapitoloDescr> </elementoCapitoloDescr> <elementoSettore /> <elementoSettoreDescr /> </elementoSommario> <intestazione>Lex 22 2015 n. 12...</intestazione> <articolato> <articolo id="art6"> <num>Art. 6</num> <rubrica>(Regolamento interno del CAL)</rubrica> <comma id="art6-com1"> <num>1. </num> <corpo>Il CAL approva...</corpo> </comma> <comma id="art6-com2"> <num>2. </num> <alinea>Il regolamento...</alinea> <el id="art6-com2-let_a"> <num>a) </num> <corpo>l'elezione...</corpo> </el> <el id="art6-com2-let_b"> <num>b) </num> <corpo>le funzioni degli organi del CAL;</corpo> </el> <el id="art6-com2-let_c"> <num>c) </num> <corpo>la costituzione...</corpo> </el> <el id="art6-com2-let_d"> <num>d) </num> <corpo>la programmazione...</corpo> </el> <el id="art6-com2-let_e"> <num>e) </num> <corpo>i casi nei...</corpo> </el> <el id="art6-com2-let_f"> <num>f) </num> <corpo>le modalità di...</corpo> </el> </comma> <comma id="art6-com3"> <num>3. </num> <corpo>Il regolamento è pubblicato...</corpo> </comma> </articolo> </articolato> </LeggeRegionale> <LeggeRegionale id="urn:nir:2014-12-12;26" xmlns="http://www.normeinrete.it/nir/2.1/"> <elementoSommario xmlns=""> <elementoCapitolo>CAP a8</elementoCapitolo> <elementoCapitoloDescr> </elementoCapitoloDescr> <elementoSettore /> <elementoSettoreDescr /> </elementoSommario> <intestazione>Lex 12 2014, n. 26....</intestazione> <articolato> <articolo id="art17"> <num>Art. 17</num> <rubrica>(Piano dell'Unione)</rubrica> <comma id="art17-com1"> <num>1. </num> <corpo>Il Piano dell'Unione...</corpo> </comma> <comma id="art17-com2"> <num>2. </num> <corpo> Il Piano ... <rif xlink:href="urn:nir:stato:decreto.legislativo:2000;267#art170" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink">articolo 170 ...</rif> . </corpo> </comma> <comma id="art17-com3"> <num>3. </num> <corpo>Il Piano dell'Unione...</corpo> </comma> <comma id="art17-com4"> <num>4. </num> <corpo>La relazione annuale...</corpo> </comma> </articolo> </articolato> </LeggeRegionale> <LeggeRegionale id="urn:nir:regione.friuli.venezia.giulia:legge:2014-12-12;26" xmlns="http://www.normeinrete.it/nir/2.1/"> <elementoSommario xmlns=""> <elementoCapitolo>CAP a14</elementoCapitolo> <elementoCapitoloDescr> </elementoCapitoloDescr> <elementoSettore /> <elementoSettoreDescr /> </elementoSommario> <intestazione>Lex 12 dicembre 2014, n. 26 ....</intestazione> <articolato> <articolo id="art5"> <num>Art. 5</num> <rubrica>(Unioni territoriali intercomunali)</rubrica> <comma id="art5-com1"> <num>1. </num> <corpo>Le Unioni territoriali...</corpo> </comma> <comma id="art5-com2"> <num>2. </num> <corpo> L'Unione ha... <rif xlink:href="urn:nir:stato:decreto.legislativo:2000-08-18;267#art32" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink">articolo 32...</rif> (Testo unico delle leggi sull'ordinamento degli enti locali). </corpo> </comma> </articolo> </articolato> </LeggeRegionale> 

Массив, который я пытаюсь построить, должен быть похож на следующий:

 Array ( [LeggeRegionale] => Array ( [intestazione] => Lex 12 2014, n. 26. [articolato] => Array ( [num] => Art. 41 [articolo] => Array ( [rubrica] => (Riforma della finanza locale) [commi] => Array ( [num_alinea] => 1. Al fine di supportare... [el] => Array ( [num_corpo] => a) definizione di... [num_corpo] => b) coordinamento della... ) [num_alinea] => 2. La revisione di... ) ) [num] => Art. 42 ... ) ) ) 

С помощью этого кода я могу читать ВСЕ XML, но это абсолютно бесполезно:

 $results = array(); $query = '//a:LeggeRegionale'; $result = $xpath->query($query); $results = array(); for($i=0; $i < $result->length; $i++) { $results[$i] = $result->item($i)->nodeValue; echo $results[$i]."<BR><BR>"; } echo "<BR>"; 

Этот код возвращает что-то структурированное (хотя это не тот массив, который я ищу), но я не понимаю, почему он возвращает только последнее появление LeggeRegionale когда я использовал foreach loop .

 foreach ($result as $entry) { $result = [ 'intestazione' => $xpath->query('//a:LeggeRegionale')->item($i)->nodeValue, 'articoli' => array( 'numero' => $xpath->query('//a:articolato/a:articolo/a:num')->item($i)->nodeValue, 'rubrica' => $xpath->query('//a:articolato/a:articolo/a:rubrica')->item($i)->nodeValue, 'commi' => array( 'numero' => $xpath->query('//a:articolato/a:articolo/a:comma/a:num')->item($i)->nodeValue, 'corpo' => $xpath->query('//a:articolato/a:articolo/a:comma/a:corpo|//a:articolato/a:articolo/a:comma/a:alinea')->item($i)->nodeValue, 'lettere' => array( 'lettera' => $xpath->query('//a:articolato/a:articolo/a:comma/a:el')->item($i)->nodeValue, ), ), ), ]; array_push($a, $result); $i++; } 

Я думаю, что есть лучший способ – благодаря XPath – читать все потомки, а не писать foreach loop для каждого уровня XML.

Преобразование сложного XML в массив приведет к … в сложном массиве. Вы считаете, что XML трудно читать, и вы считаете, что массивы намного проще для вас, поэтому массив должен быть решением. Но на самом деле XML хорошо подходит для разбора дерева в PHP. Массив недоступен. Например, вы не можете запустить запрос xpath в массиве.

А для массива у вас есть ошибка в вашем псевдо-массиве, что у вас есть дубликаты ключей. Структура больше похожа:

 Array ( [LeggeRegionale] => Array ( [0] => Array ( [intestazione] => Lex 12 2014, n. 26. [articolato] => Array ( [articolo] => Array ( [0] => Array ( [num] => Art. 41 [rubrica] => (Riforma della finanza locale) [commi] => Array ( [0] => Array ( [num_alinea] => 1. Al fine di supportare... [num_corpo] => Array ( [0] => a) definizione di... [1] => b) coordinamento della... [2] => c) definizione delle... [3] => d) la disciplina... ) ) [1] => Array ( [num_alinea] => 2. La revisione di... [num_corpo] => Array ( [0] => a) razionalizzazione e... articolo 1, comma 154, della legge 13 dicembre 2010, n. 220 (Legge di stabilità 2011); [1] => b) applicazione dei... articolo 119 della Costituzione , nonché del principio... [2] => c) valorizzazione... [3] => d) previsione di... [4] => e) valorizzazione del... [5] => f) previsione di... ) 

И это уже с некоторой оптимизацией (вы можете игнорировать неправильные символы с кодировкой, это ошибка копирования и вставки).

Возможно, вам захочется воспользоваться библиотекой, которая упростит запрос дочерних узлов через xpath напрямую. Я дал ответ, который показывает небольшой и быстрый пример использования DOMXPath и php функции query , вам нужно будет добавить поддержку пространства имен для этого. Затем вам нужно будет позаботиться о построении массива, что на самом деле довольно сложно:

 $doc = new DOMDocument(); $doc->load('example.xml'); /* DOMBLAZE II XMLNS */ $doc->registerNodeClass("DOMElement", "DOMBLAZE"); # ... /** @var $root DOMBLAZE */ $root = $doc->documentElement; $root()->registerNamespace('a', 'http://www.normeinrete.it/nir/2.1/'); $array = []; foreach ($root('a:LeggeRegionale') as $leggioRegionale) { $entry = []; $entry['intestazione'] = $leggioRegionale('string(./a:intestazione)'); $articolato = []; foreach ($leggioRegionale('a:articolato/a:articolo') as $articolo) { } $array[] = $entry; } print_r($array); 

Этот пример (очевидно) неполный.

В качестве альтернативы я экспериментировал с записью выражений xpath в самом XML, который определяет «массив». Это можно было бы использовать с адаптированным SimpleXMLElement для построения массива рекурсивно на основе определения:

 $doc = new DOMDocument(); $doc->load('example.xml'); $buffer = <<<XML <xmlarray> <xml> <namespace prefix="a" uri="http://www.normeinrete.it/nir/2.1/"/> </xml> <array> <LeggeRegionale expr="a:LeggeRegionale"> <intestazione expr="string(a:intestazione)"/> <articolato expr="a:articolato"> <articolo expr="a:articolo"> <num expr="string(a:num)"/> <rubrica expr="string(a:rubrica)"/> <commi expr="a:comma"> <num_alinea expr="concat(a:num, a:alinea)"/> <el expr="a:el" alias="num_corpo"> <num_corpo expr="normalize-space(concat(a:num, a:corpo))" cast="string"/> </el> </commi> </articolo> </articolato> </LeggeRegionale> </array> </xmlarray> XML; $xmlArray = new XmlArrayElement($buffer); $xmlArray->assignDocument($doc); print_r($xmlArray->toArray()); 

Это эффективно создает массив, представленный в начале ответа.

Конечно, теперь это выглядит как супер-решение для вас, но все, что было сделано, это перенос дерева XML в другое дерево, на этот раз в массиве. XmlArrayElement не является частью примера в ответе, а в контексте .

Возможно, лучше использовать рекурсию для создания другого документа XML на лету.

Также стоит рассмотреть в вашем случае XSLT, который технически был сделан для этого. Вы можете напрямую конвертировать в HTML-документ. HTML-документ гораздо более переносимый, чем документы RTF, и существуют существующие инструменты для их преобразования в RTF, а также другие документы.