php simplexml_load_string忽略元素

时间:2017-06-11 12:24:41

标签: php xml parsing xml-parsing

也许你可以帮助我:我尝试解析这个xml文件

<norm>

    <metadaten>
        <jurabk>GWB</jurabk>
        <enbez>§ 99</enbez>
        <titel format="XML">Öffentliche Auftraggeber</titel>
    </metadaten>

    <textdaten>

        <text format="XML">
            <Content>
                <P>Öffentliche Auftraggeber sind 
                    <DL Type="arabic">
                        <DT>1.</DT>
                        <DD Font="normal">
                            <LA>Gebietskörperschaften sowie deren Sondervermögen,</LA>
                        </DD>
                    </DL>
                </P>
            </Content>
        </text>

        <fussnoten>
            <Content>
                <P>(+++ § 99: Zur Anwendung vgl. § 41 Abs. 2 MessbG +++)</P>
            </Content>
        </fussnoten>

    </textdaten>

</norm>

使用以下方法解析时:

$xml=simplexml_load_string($xmlStr) or die("Error: Cannot create object");

echo "<pre>";
print_r($xml);
echo "</pre>";

它忽略了&#34; DL&#34;中的部分。路径 norm-&gt; textdaten-&gt; text-&gt; Content-&gt; P不完整。

结果是:

SimpleXMLElement Object
(
   [metadaten] => SimpleXMLElement Object
    (
      [jurabk] => GWB
      [enbez] => § 99
      [titel] => Öffentliche Auftraggeber
    )

    [textdaten] => SimpleXMLElement Object
    (
        [text] => SimpleXMLElement Object
         (
          [@attributes] => Array
            (
              [format] => XML
            )
          [Content] => SimpleXMLElement Object
           (
             [P] => Öffentliche Auftraggeber sind
           )
         )

        [fussnoten] => SimpleXMLElement Object
         (
          [Content] => SimpleXMLElement Object
            (
               [P] => (+++ § 99: Zur Anwendung vgl. § 41 Abs. 2 MessbG +++)
            )
        )
    )
)

您是否知道如何正确解析它?

也许simplexml_load_string函数无法检索文本BETWEEN

和DL ??

谢谢!

2 个答案:

答案 0 :(得分:0)

因为xml中有文本和标签的混合。您必须修改xml作为其分隔标记。我在这里添加了TEST标记。你可以随意改变它

<?php
$xmlStr = '<norm>
   <metadaten>
      <jurabk>GWB</jurabk>
      <enbez>§ 99</enbez>
      <titel format="XML">Öffentliche Auftraggeber</titel>
   </metadaten>
   <textdaten>
      <text format="XML">
         <Content>
            <P>
               <TEST>Öffentliche Auftraggeber sind</TEST>
               <DL Type="arabic">
                  <DT>1.</DT>
                  <DD Font="normal">
                     <LA>Gebietskörperschaften sowie deren Sondervermögen,</LA>
                  </DD>
               </DL>
            </P>
         </Content>
      </text>
      <fussnoten>
         <Content>
            <P>(+++ § 99: Zur Anwendung vgl. § 41 Abs. 2 MessbG +++)</P>
         </Content>
      </fussnoten>
   </textdaten>
</norm>';

$xml=simplexml_load_string($xmlStr) or die("Error: Cannot create object");

echo "<pre>";
print_r($xml);
echo "</pre>";

在此处查看o / p:https://eval.in/815329

答案 1 :(得分:0)

它不会忽略它们。调试输出不显示所有可访问的数据,因为它取决于您如何访问它。例如,如果您将属性用作列表(foreach)或字符串,则会有所不同。

在您的情况下,问题是SimpleXML如何处理节点的文本内容。它仅返回第一个文本子节点的内容。在DOM中,这是一个属性$textContent,它包含所有后代节点的文本内容。因此,获取文本的最简单方法是将SimpleXMLElement转换为DOMElement实例。

$xml = <<<'XML'
<div>
  <p>
    Some Text
    <dl>
      <dd>in descendant nodes</dd>
    </dl>
  </p>
</div>
XML;

$div = new SimpleXMLElement($xml);
// only the first text child
var_dump((string)$div->p);  
// all text content
var_dump(dom_import_simplexml($div->p)->textContent);

输出:

string(22) "
    Some Text

  "
string(53) "
    Some Text

      in descendant nodes

  "

这包括空白节点(仅包含换行符,空格等的节点)。因此,根据您之后使用文本内容的方式,您可能需要使用字符串函数进行清理。

XML片段

如果您不仅需要XML而且需要整个节点作为XML字符串,则可以使用SimpleXMLElement::asXml()DOMDocument::saveXml()

$div = new SimpleXMLElement($xml);
var_dump($div->p->asXml());  

$node = dom_import_simplexml($div->p);
var_dump($node->ownerDocument->saveXml($node));

DOM允许一些选项并保存HTML。

要保存p内的所有子节点,请迭代DOMNode::$childNodes。请注意,这不仅包括元素,还包括文本节点,注释......

$node = dom_import_simplexml($div->p);
$result = '';
foreach ($node->childNodes as $child) {
  $result .= $node->ownerDocument->saveXml($child);
}
var_dump($result);

使用Xpath可以轻松迭代特定节点。查找SimpleXMLElement::xpath()DOMXpath::evaluate()