【问题标题】:help in reading nested xml using xmlreader in php帮助在 php 中使用 xmlreader 读取嵌套的 xml
【发布时间】:2009-02-09 06:15:23
【问题描述】:
<root>
  <thing>
    <specs>
      <spec1 />
      <spec3 />
      <spec2 />
    </specs>
    <details />
    <more_info>
      <info1 />
      <info2 />
    </more_info>
  </thing>
</root>


okeee 所以我得到了这个示例 xml,问题是我似乎无法获取 innerxml 的值,
当我使用 $reader-&gt;readInnerXML() 它返回整个字符串虽然我确定我的 xml 是有效的
我想要的是分别获取 spec1、spec2、spec3 的值

代码很长,所以我发布了它here
我已经坚持了 3 天了 T_T 可怜的我,我很乐意接受任何更正

【问题讨论】:

  • 您的问题到底是什么?你不希望 innerXML 是一个字符串?
  • 很抱歉,我编辑了这个问题,我想要的是能够获取名为 spec1、spec2、spec3、info1 和 info2 的属性的值
  • spec1、spec2、spec3、info1 和 info2 不是属性。它们是没有属性或子节点的节点。

标签: php xmlreader


【解决方案1】:

这取决于您所说的“价值”。如果你有类似的东西

<spec3 />Value</spec3>

那么 readInnerXML 应该会给你你的价值。

如果你的值在属性中,

<spec1 foo="my attribute" />

您需要使用 XMLReader 对象的 getAttribute 方法,或者明确告诉阅读器开始解析属性。请参阅下面的代码示例,了解实现此目的的几种方法。

最后,如果节点包含更多嵌套的XML,

<spec2><foo><baz thing="la de da">Value</baz></foo></spec2>

当时没有直接的方法让读者了解其中的值/元素。您需要执行以下操作之一

  1. 更改您的阅读器解析代码以挂钩到这些深度的元素
  2. 从 readInnerXML 中获取 XML 块并使用第二个 XMLReader 实例开始解析它,
  3. 从 readInnerXML 中获取 XML 块并开始使用另一个 XML 解析库对其进行解析。

这是一些解析属性的示例代码

$reader = new XMLReader();
$reader->xml(trim('
<root>
  <thing>
    <specs>
      <spec1 foo="my attribute">Value</spec1>
      <spec3>
      My Text
      </spec3>
      <spec2 foo="foo again" bar="another attribute" baz="yet another attribute" />
    </specs>
    <details />
    <more_info>
      <info1 />
      <info2 />
    </more_info>
  </thing>
</root> 
'));

$last_node_at_depth = array();
$already_processed  = array();
while($reader->read()){
    $last_node_at_depth[$reader->depth] = $reader->localName;
    if(
    $reader->depth > 0 && 
    $reader->localName != '#text' &&   
    $last_node_at_depth[($reader->depth-1)] == 'specs' &&
    !in_array ($reader->localName,$already_processed)
    ){          
        echo "\n".'Processing ' . $reader->localName . "\n";
        $already_processed[] = $reader->localName;
        echo '--------------------------------------------------'."\n";
        echo 'The Value for the inner node ';           
        echo ' is [';
        echo trim($reader->readInnerXML());
        echo ']'."\n";

        if($reader->attributeCount > 0){
            echo 'This node has attributes, lets process them' . "\n";

            //grab attribute by name
            echo '    Value of attribute foo: ' . $reader->getAttribute('foo') . "\n";

            //or use the reader to itterate through all the attributes
            $length = $reader->attributeCount;
            for($i=0;$i<$length;$i++){
                //now the reader is pointing at attributes instead of nodes
                $reader->moveToAttributeNo($i);
                echo '    Value of attribute ' . $reader->localName;
                echo ': ';
                echo $reader->value;
                echo "\n";
            }
        }
        //echo $reader->localName . "\n";        
    }        
}

【讨论】:

    【解决方案2】:

    这工作as advertised

    readInnerXML

    读取当前节点的内容,包括子节点和标记。

    我认为您的困惑可能在于节点和属性之间。 &lt;spec1 /&gt; 不是属性 - 它是一个没有任何子节点的节点。写&lt;spec1 /&gt; 只是&lt;spec1&gt;&lt;/spec1&gt; 的简写。所以你需要的是使用实际属性:

    <root>
      <thing>
        <specs spec1="" spec3="" spec2="" />
        <details />
        <more_info info1="" info2="" />
      </thing>
    </root>
    

    或读取这些节点。

    无论如何。我不确定这是否只是因为您向我们展示了一些示例代码,但是命名节点spec1spec2spec3 等可能不是一个好主意。节点名称在 XML 中不需要是唯一的。

    【讨论】:

      【解决方案3】:

      不确定这是否是您要问的,但 simplexml 可用于读取 xml 数据(每个元素的值,而不是属性)。对于您的事物/规格示例,请执行以下操作:

      $xmlobj = simplexml_load_file($xmlfile);
      $extracteddata = $xmlobj->thing->specs->spec1;
      

      会给你 spec1 元素的内容。

      例如:如果元素是&lt;spec1&gt;1234&lt;/spec1&gt;,上面的代码将返回“1234”

      【讨论】:

      • 嗯,我在文档(用户 cmets)中读到简单的 xml 不适用于非常大的 xml 文件......所以我求助于 xmlreader,因为我正在处理的文件约为 46mb
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2012-10-20
      • 1970-01-01
      • 2023-03-30
      • 2017-02-25
      • 1970-01-01
      相关资源
      最近更新 更多