3

これが私が使用しているxmlの例です:

<contact id="43956">
 <personal>
      <name>
           <first>J</first>
           <middle>J</middle>
           <last>J</last>
           Some text...
      </name>
      <title>Manager</title>
      <employer>National</employer>
      <dob>1971-12-22</dob>
 </personal>
</contact>

取得しましたSome text...が、xmlドキュメント全体を読み取るためのコードが必要になりました。また、xml内の値を読み取っていません...これまで使用したことがないことがわかりますXMLReader

これは私が得るものです:

Array ( [contact] => Array ( [id] => 43956 [value] => some sample value ) [first] => [middle] => [last] => [#text] => Some text... [name] => [title] => [employer] => [dob] => [personal] => )

これが私が今持っているコードです:

function xml2array($file, array $result = array()) {
$lastElementNodeType = '';
$xml = new XMLReader();
if(!$xml->open($file)) {
    die("Failed to open input file");
}
while($xml->read()) {
    switch ($xml->nodeType) {
        case $xml::END_ELEMENT:
            $lastElementNodeType = $xml->nodeType;
        case $xml::TEXT:
            $tag = $xml->name;
            if($lastElementNodeType == 15) {
                $result[$tag] = $xml->readString();                 
            }
        case $xml::ELEMENT:
            $lastElementNodeType = $xml->nodeType;
            $tag = $xml->name;
            if($xml->hasAttributes) {
                while($xml->moveToNextAttribute()) {
                    $result[$tag][$xml->name] = $xml->value;
                }
            }
    }
}
print_r($result);
}

この関数を再帰的にすることを考えましたが、それを試してみると、配列が非常に乱雑になりました。

私はこれのバージョンを持っていましたが、それでも、などに出力Jされませんでした。first

function xml2assoc($xml) { 
$tree = null; 
while($xml->read()) 
    switch ($xml->nodeType) { 
        case XMLReader::END_ELEMENT: return $tree; 
        case XMLReader::ELEMENT: 
            $node = array('tag' => $xml->name, 'value' => $xml->isEmptyElement ? '' : xml2assoc($xml)); 
            if($xml->hasAttributes) 
                while($xml->moveToNextAttribute()) 
                    $node['attributes'][$xml->name] = $xml->value; 
            $tree[] = $node; 
        break; 
        case XMLReader::TEXT: 
        case XMLReader::CDATA: 
            $tree .= $xml->value; 
    } 
return $tree; 
}
4

1 に答える 1

0

1を取る

最近のノードのタイプまたは少なくとも最後のノードのタイプを保存して、テストできるようにする必要があると思います。つまり、少なくともサンプルXMLでそれを提示すると、ノードタイプ、探しているテキストを含むノードタイプ、そして別のノードタイプに遭遇することにELEMENT_ENDなりTEXTますELEMENT_END

したがって、が必要case $xml::TEXTになります。また、以前のノードタイプを保存して、パーサーが通常の状況では新しいELEMENTイベントまたはイベントを予期しているはずなのにEND_ELEMENT、代わりに受信したことを認識できるようにする必要があります。文章。readString()これは、テキストを一時変数にキャプチャして目的のために保存するか、次のノードもELEMENT_ENDその時点で保存して一時変数をクリアできるかどうかを確認するために必要なシグナルになります。

2を取る

最終的に何を望んでいるのかがもう少しわかったので(つまり、ツリー全体から特定の情報だけでなく、ツリー全体をキャプチャしようとしているので)、関数の再帰バージョンを使用することをお勧めします。 。私はあなたが持っているものを少し変更しました(主な実質的な変更についてはTEXTとCDATAのケースを参照してください)。

function xml2assoc($xml)
{
    $tree = null;
    while($xml->read())
    {
        switch ($xml->nodeType)
        {
            case XMLReader::END_ELEMENT:
                return $tree;
            case XMLReader::ELEMENT: 
                $node = array('tag' => $xml->name, 'value' => $xml->isEmptyElement ? '' : xml2assoc($xml));
                if($xml->hasAttributes)
                    while($xml->moveToNextAttribute()) 
                        $node['attributes'][$xml->name] = $xml->value; 
                $tree[] = $node;
                break;
            case XMLReader::TEXT:
                $tree["text"] = $xml->value;
                break;
            case XMLReader::CDATA:
                $tree["cdata"] = $xml->value;
                break;
        }
    }
    return $tree;
}

この場合の出力は次のようになります。

Array
(
    [0] => Array
        (
            [tag] => contact
            [value] => Array
                (
                    [0] => Array
                        (
                            [tag] => personal
                            [value] => Array
                                (
                                    [0] => Array
                                        (
                                            [tag] => name
                                            [value] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [tag] => first
                                                            [value] => Array
                                                                (
                                                                    [text] => J
                                                                )
                                                        )
                                                    [1] => Array
                                                        (
                                                            [tag] => middle
                                                            [value] => Array
                                                                (
                                                                    [text] => J
                                                                )
                                                        )
                                                    [2] => Array
                                                        (
                                                            [tag] => last
                                                            [value] => Array
                                                                (
                                                                    [text] => J
                                                                )
                                                        )
                                                    [text] => Some text...
                                                )
                                        )
                                    [1] => Array
                                        (
                                            [tag] => title
                                            [value] => Array
                                                (
                                                    [text] => Manager
                                                )
                                        )
                                    [2] => Array
                                        (
                                            [tag] => employer
                                            [value] => Array
                                                (
                                                    [text] => National
                                                )
                                        )
                                    [3] => Array
                                        (
                                            [tag] => dob
                                            [value] => Array
                                                (
                                                    [text] => 1971-12-22
                                                )
                                        )
                                )
                        )
                )
            [attributes] => Array
                (
                    [id] => 43956
                )
        )
)

私たちはこれがあなたがマイナーな編集で何をしようとしているのかを推測しますが、私たちは実際にここで車輪の再発明をしているだけです。解析する必要のあるXMLが特に大きくないことを願っています。

于 2012-12-23T03:24:23.640 に答える