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


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

代码很长,所以我把它贴在这里
我已经坚持了 3 天了 T_T 可怜的我,我很乐意接受任何更正

4

3 回答 3

4

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

<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";        
    }        
}
于 2009-02-09T18:00:33.907 回答
0

就像宣传的那样工作:

读取InnerXML

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

我认为您的混淆可能在节点和属性之间。<spec1 />不是属性 - 它是一个没有任何子节点的节点。写作<spec1 />只是<spec1></spec1>. 所以你需要的是使用实际属性:

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

或读取这些节点。

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

于 2009-02-09T09:29:31.250 回答
0

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

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

会给你 spec1 元素的内容。

例如:如果元素是<spec1>1234</spec1>上面的代码将返回“1234”

于 2009-02-09T11:08:27.270 回答