PHP的XPath。转换复杂的XML数组 [英] PHP XPath. Convert complex XML to array

查看:169
本文介绍了PHP的XPath。转换复杂的XML数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

三天后试图通过自己去解决问题我不得不放弃。这是来自意大利的法律分贝导出一个巨大的XML的摘录。我想这个XML转换为PHP数组作为我们的目标是使用数组使用PHP类PHP2RTF建立一个格式化的Word文档。

After three days attempting to work it out by myself I have to give up. This is an excerpt of a huge XML exported from a dB of italian laws. I would like to convert this XML to a PHP array as the goal is to use the array to build a formatted Word document using a PHP class as 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>

我试图建立应类似于下面的数组:

The array I'm trying to build should be similar to the following:

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
                     ...
                  )
           )
   )

有了这个code,我可以读取所有的XML,但它绝对无用:

With this code I can read ALL the XML but it's absolutely useless:

$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>";

这code不会返回结构化的东西(虽然这不是我要找的数组),但我不明白为什么它是只返回 LeggeRegionale 时,我用了一个 foreach循环

This code does return something structured (although it is not the array I'm looking for) but I don't understand why it's returning only the last occurrence of LeggeRegionale when I used a 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循环为每个XML级

推荐答案

复杂的XML转换到一个数组将导致......在一系列复杂。你会发现在XML难​​以阅读和你认为阵列更容易为你的数组必须是解决方案。但实际上XML非常适合于树解析PHP中。数组是不是访问。例如,您不能运行阵列上XPath查询。

Converting complex XML into an array will result ... in a complex array. You find the XML difficult to read and you think that arrays are much easier for you so the array must be the solution. But actually XML is well suited for tree parsing in PHP. An array isn't as accessible. For example, you can't run an xpath query on an array.

和为阵,你有,你有重复键的伪数组中的错误。该结构看起来更像是:

And for the array, you have the mistake in your pseudo-array that you have duplicate keys. The structure looks more like:

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...
                                                                )

...

和已与一些优化(你可以忽略与编码错误的字符,这是一个复制和放大器;粘贴错误)。

And that is already with some optimization (you can ignore the wrong characters with the encoding, this is a copy & paste error).

您也许想利用这使得它更容易通过的XPath直接查询子节点的库。我已经给了一个答案,显示一个小&安培;简单的例子中的 使用DOMXPath和功能查询PHP 的,你需要的添加命名空间支持了点。那么你就需要采取数组的建设,这实际上是相当复杂的护理:

You perhaps want to make use of a library that makes it easier to query child-nodes via xpath directly. I've given an answer that show a small & quick example in use DOMXPath and function query php, you would need to add namespace support for that. You then would need to take care of the array building, which actually is quite complex:

$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);

这例子是(显然)不完整的。

This example is (obviously) incomplete.

另外我尝试写下来以XML本身定义的阵中的XPath前pressions。然后,这可能与使用的量身定制的的SimpleXMLElement 根据定义的递归建立数组:

Alternatively I experimented writing down the xpath expressions in an XML itself which defines the "array". This then could be used with a tailored SimpleXMLElement to build the array recursively based on the definition:

$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());

这也有效地产生在答案的开始psented数组$ P $。

This does effectively produce the array presented in the beginning of the answer.

当然这个现在看起来像超级解决方案给你,但它所作的只是包装XML树到另一棵树,这一次在数组中。的 <青霉> XmlArrayElement 的是不是在回答的例子的一部分,但在一个要旨

Sure this now looks like the super solution to you, but all it did was wrapping the XML tree into another tree, this time in an array. The XmlArrayElement is not part of the example in the answer but in a gist.

这也许更好地利用递归来动态创建另一个XML文档。

It's perhaps better to make use of the recursion to create another XML document on the fly.

另外值得你的情况考虑将由XSLT在技术上已经取得了点。你可以直接转换成HTML文档英寸HTML文档都远远超过RTF文档更轻便并有现有的工具将它们转换成RTF,还包括其他文档。

Also worth a consideration in your case would by XSLT which technically has been made for that. You could directly convert in a HTML document. HTML document are much more portable than RTF documents and there are existing tools to convert them into RTF but also other documents.

这篇关于PHP的XPath。转换复杂的XML数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆