1

名前空間を含む XML レコードセットを反復処理する方法を見つけようとしています。ただし、事前にフィールド名がわかりません。サンプル XML を以下に示します。

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.site.com/SMART/Updates">
<NewDataSet>
    <record>
        <FIELD1>data1</FIELD1>
        <FIELD2>data2</FIELD2>
        <FIELD3>data3</FIELD3>
    </record>
    <record>
        <FIELD1>data1</FIELD1>
        <FIELD2>data2</FIELD2>
        <FIELD3>data3</FIELD3>
    </record>
</NewDataSet>

繰り返しますが、事前にフィールド名はわかりません。名前空間を読み取り、ルート要素の名前 (この場合は「NewDataSet」) を見つけてから、個々の要素のフィールド名と値を取得する必要があります。$xml->getname() と $xml->xpath('\') を使用してルート要素名を見つけようとしましたが、クラックできませんでした。

4

4 に答える 4

0

別の回答で投稿されたチャットのトランスクリプトを見ると、要素には実際にはエスケープされたXMLドキュメントである文字列が含まれているように見えます。したがって、外部ドキュメントには、と呼ばれる要素が1つだけあります<string>。子はなく、コンテンツだけです。(これは、ASP.netのサービスビルダーを使用している人のように見えます。)

したがって、欠落しているステップは、この内部XMLをエスケープ解除して、新しいXMLドキュメントとして扱うことです。

// Parse the outer XML, which is just one <string> node
$wrapper_sx = simplexml_load_string($wrapper_xml);
// Extract the actual XML inside it
$response_xml = (string)$wrapper_sx;
// Parse that
$response_sx = simplexml_load_string($response_xml);

// Now handle the XML
$tag_name = $response_sx->getName();
foreach ( $response_sx->children() as $child )
{
    // Etc
}

// see http://github.com/IMSoP/simplexml_debug
simplexml_tree($response_sx, true);
于 2012-10-17T17:23:39.263 に答える
0

XMLは無効ですが、文字列タグがタグの後に閉じられていると仮定します</NewDataSet>

を使用して、ドキュメントで宣言されている名前空間を取得できますgetDocNamespaces()

$xml = simplexml_load_string($xmlfile);
$namespaces = $xml->getDocNamespaces(); //array of namespaces

$dataset = $xml->children(); //first child (NewDataSet)

echo $dataset->getName(); //NewDataSet

$records = $dataset->children();
$i = 0;
$result = array();
foreach ($records as $key => $value) {
    foreach ($value as $fieldName => $fieldData) {
        $result[$i][$fieldName] = (string)$fieldData;
    }
    $i++;
}
var_dump($result);

$result読みやすく、行を含む配列が含まれるようになりました。

array(2) {
  [0]=> array(3) {
            ["FIELD1"]=> string(5) "data1"
            ["FIELD2"]=> string(5) "data2"
            ["FIELD3"]=> string(5) "data3"
        }
  [1]=>  array(3) {
            ["FIELD1"]=> string(5) "data1"
            ["FIELD2"]=> string(5) "data2"
            ["FIELD3"]=> string(5) "data3"
        }
}
于 2012-10-07T09:11:16.780 に答える
0

私は実際にあなたの問題が何であるかを理解していません。あなたが PHP chatで与えた実際の XML には、名前空間が含まれていません (たとえそうであったとしても!)。

ドキュメント要素からタグ名を読み取るだけです。

# echoes NewDataSet / string (depending on which XML input)
echo dom_import_simplexml($simplexml)->ownerDocument->documentElement->tagName;

別の XML ドキュメント内に実際に XML ドキュメントがある場合は、次の操作を実行できます。

// load outer document
$docOuter = new DOMDocument();
$docOuter->loadXML($xmlString);

// load inner document
$doc = new DOMDocument();
$doc->loadXML($docOuter->documentElement->nodeValue);

echo "Root element is named: ", $doc->documentElement->tagName, "\n";

または、SimpleXML を好む場合:

echo "Root element is named: ",
      simplexml_load_string(simplexml_load_string($xmlString))->getName()
;
于 2012-10-16T22:22:28.523 に答える
0

(チャットで議論されているように)

単純な DOM 関数は、XML を処理する最良の方法です。

デモまたはコード:

<?php
header('Content-Type: text/plain');
$xml = <<<END
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.site.com/SMART/Updates">
<NewDataSet>
    <record>
        <FIELD1>data1</FIELD1>
        <FIELD2>data2</FIELD2>
        <FIELD3>data3</FIELD3>
    </record>
    <record>
        <FIELD1>data1</FIELD1>
        <FIELD2>data2</FIELD2>
        <FIELD3>data3</FIELD3>
    </record>
</NewDataSet>
</string>
END;
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->normalize();
$dom->loadXML($xml);
echo 'Root element name: ' . $dom->firstChild->firstChild->tagName . PHP_EOL;
echo 'Number of child elements: ' . count($dom->firstChild->firstChild->childNodes) . PHP_EOL;
echo '=====' . PHP_EOL . PHP_EOL;
echo print_node($dom->firstChild->firstChild);
function print_node($node, $level = 0, $prev_level = 0) {
    $result = '';
    if($node->hasChildNodes()) {
        foreach($node->childNodes as $subnode) {
            $result .= str_repeat('    ', $level) . $node->tagName . ' =>' . PHP_EOL;
            $result .= print_node($subnode, $level + 1, $level) . PHP_EOL;
        }
    } else {
        if(trim($node->nodeValue) !== '') {
            $result .= str_repeat('    ', $level) . '**Data: ' . trim($node->nodeValue) . PHP_EOL;
        }
    }
    return $result;
}
?>

出力:

Root element name: NewDataSet
Number of child elements: 1
=====

NewDataSet =>
    record =>
        FIELD1 =>
            **Data: data1


    record =>
        FIELD2 =>
            **Data: data2


    record =>
        FIELD3 =>
            **Data: data3



NewDataSet =>
    record =>
        FIELD1 =>
            **Data: data1


    record =>
        FIELD2 =>
            **Data: data2


    record =>
        FIELD3 =>
            **Data: data3
于 2012-10-16T23:34:58.013 に答える