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 无效,但假设字符串标记在</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 回答
0

查看另一个答案中发布的聊天记录,看起来该元素实际上包含一个字符串,该字符串是一个转义的XML 文档。因此,外部文档中只有一个元素,称为<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 回答