我试图找到一种方法来遍历包含命名空间的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-&gt; getname()和$ xml-&gt; xpath('\')来查找根元素名称,但无法破解它。
答案 0 :(得分: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"
}
}
答案 1 :(得分:0)
我实际上并不了解你的问题,在said real-life XML you gave in PHP chat中,没有涉及名称空间(即使!)。
只需从文档元素中读出标记名称:
# 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()
;
答案 2 :(得分:0)
Plain DOM functions是处理XML的最佳方式。
Demo或代码:
<?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
答案 3 :(得分:0)
查看the chat transcript posted in another answer,该元素实际上包含一个字符串,该字符串是转义 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);