从 asXML() 获取 XML 个标签
Get XML tags from asXML()
我正在解析 XML
文档并使用 asXML()
获取嵌套标签的值。这工作正常,但我想将此数据移动到一个 MySQL
数据库中,该数据库的列与文件的标签相匹配。那么基本上我如何获得 asXML()
从中提取文本的标签?
这样我最终可以做类似的事情:INSERT INTO db.table (TheXMLTag) VALUES ('XMLTagText');
这是我目前的代码:
$xml = simplexml_load_file($target_file) or die ("Error: Cannot create object");
foreach ($xml->Message->SettlementReport->SettlementData as $main ){
$value = $main->asXML();
echo '<pre>'; echo $value; echo '</pre>';
}
foreach ($xml->Message->SettlementReport->Order as $main ){
$value = $main->asXML();
echo '<pre>'; echo $value; echo '</pre>';
}
这就是我的文件的样子,可以给你一个想法(所以基本上我如何获得 [SettlementData]、[0]、[Fulfillment]、[Item] 等中的标签?):
我尝试使用 SimpleXML
but it skips text data. However, using the Document Object Model
扩展程序。
这个 returns 一个数组,其中每个元素都是一个包含 2 个键的数组:tag
和 text
,按照树的遍历顺序返回。
<?php
// recursive, pass by reference (spare memory ? meh...)
// can skip non tag elements (removes lots of empty elements)
function tagData(&$node, $skipNonTag=false) {
// get function name, allows to rename function without too much work
$self = __FUNCTION__;
// init
$out = array();
$innerXML = '';
// get document
$doc = $node->nodeName == '#document'
? $node
: $node->ownerDocument;
// current tag
// we use a reference to innerXML to fill it later to keep the tree order
// without ref, this would go after the loop, children would appear first
// not really important but we never know
if(!(mb_substr($node->nodeName,0,1) == '#' && $skipNonTag)) {
$out[] = array(
'tag' => $node->nodeName,
'text' => &$innerXML,
);
}
// build current innerXML and process children
// check for children
if($node->hasChildNodes()) {
// process children
foreach($node->childNodes as $child) {
// build current innerXML
$innerXML .= $doc->saveXML($child);
// repeat process with children
$out = array_merge($out, $self($child, $skipNonTag));
}
}
// return current + children
return $out;
}
$xml = new DOMDocument();
$xml->load($target_file) or die ("Error: Cannot load xml");
$tags = tagData($xml, true);
//print_r($tags);
?>
I would like to move this data into a MySQL database whose columns match the tags of the file.
你的问题是双重的。
问题的第一部分是对数据库结构做内省。即获取所有table个名字,获取这些的列名。大多数现代数据库都提供此功能,MySQL 也是如此。在 MySQL 中,这些是 INFORMATION_SCHEMA Tables。您可以像查询普通数据库 table 一样查询它们。我通常推荐 PDO 因为 PHP,mysqli 自然也能完美地完成这项工作。
第二部分是解析 XML 数据并将其数据映射到数据库 tables(您使用 SimpleXMLElement因为在你的问题中,所以我与它相关特别是)。为此,您首先需要了解如何将 XML 中的数据映射到数据库中。 XML 文件不像关系数据库 table 那样具有二维结构,但它具有树结构。
例如(如果我没看错你的问题)你将 Message->SettlementReport->SettlementData
识别为第一个 "table" .对于那个 specific 示例,它很容易,因为 <SettlementData>
只有可以表示列名称(元素名称)和值(文本内容)的子元素。为此很容易:
header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $name => $value ) {
echo $name, ': ', $value, "\n";
}
如您所见,在 foreach
子句中指定 key 赋值将为您提供带有 简单XML元素。或者,SimpleXMLElement::getName()
方法做同样的事情(只是一个例子,只是代码略有不同):
header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $value) {
$name = $value->getName();
echo $name, ': ', $value, "\n";
}
在这种情况下,您受益于以下事实:foreach
中提供的 Iterator SimpleXMLElement
您通过 $xml->...->SettlementData
访问遍历所有子元素。
这里的 Xpath 是一个更通用的概念。所以请耐心等待我向您展示第三个示例,它再次执行类似的输出:
header('Content-Type: text/plain; charset=utf-8');
$rows = $xml->xpath('/*/Message/SettlementReport/SettlementData');
foreach ($rows as $row) {
foreach ($row as $column) {
$name = $column->getName();
$value = (string) $column;
echo $name, ': ', $value, "\n";
}
}
然而,如前所述,将树结构(N 深度)映射到二维结构(数据库 table)现在可能总是那么简单。
如果您正在寻找可能的结果(最常见的是数据丢失或数据重复),给出了一个更复杂的PHP示例在之前的问答中:
- How excel reads XML file?
- PHP XML to dynamic table
请注意:事实上,这种映射本身可能很复杂,问题和答案继承自这种复杂性。这首先意味着这些可能不容易阅读,而且 - 或许更突出 - 可能不适用于您的问题。这些只是为了拓宽您的视野,并为某些场景提供一些示例。
希望对您有所帮助,请在下方以评论的形式提供任何反馈。您的问题可能会或可能不会更严重,因此希望这可以帮助您决定 how/where 继续。
我正在解析 XML
文档并使用 asXML()
获取嵌套标签的值。这工作正常,但我想将此数据移动到一个 MySQL
数据库中,该数据库的列与文件的标签相匹配。那么基本上我如何获得 asXML()
从中提取文本的标签?
这样我最终可以做类似的事情:INSERT INTO db.table (TheXMLTag) VALUES ('XMLTagText');
这是我目前的代码:
$xml = simplexml_load_file($target_file) or die ("Error: Cannot create object");
foreach ($xml->Message->SettlementReport->SettlementData as $main ){
$value = $main->asXML();
echo '<pre>'; echo $value; echo '</pre>';
}
foreach ($xml->Message->SettlementReport->Order as $main ){
$value = $main->asXML();
echo '<pre>'; echo $value; echo '</pre>';
}
这就是我的文件的样子,可以给你一个想法(所以基本上我如何获得 [SettlementData]、[0]、[Fulfillment]、[Item] 等中的标签?):
我尝试使用 SimpleXML
but it skips text data. However, using the Document Object Model
扩展程序。
这个 returns 一个数组,其中每个元素都是一个包含 2 个键的数组:tag
和 text
,按照树的遍历顺序返回。
<?php
// recursive, pass by reference (spare memory ? meh...)
// can skip non tag elements (removes lots of empty elements)
function tagData(&$node, $skipNonTag=false) {
// get function name, allows to rename function without too much work
$self = __FUNCTION__;
// init
$out = array();
$innerXML = '';
// get document
$doc = $node->nodeName == '#document'
? $node
: $node->ownerDocument;
// current tag
// we use a reference to innerXML to fill it later to keep the tree order
// without ref, this would go after the loop, children would appear first
// not really important but we never know
if(!(mb_substr($node->nodeName,0,1) == '#' && $skipNonTag)) {
$out[] = array(
'tag' => $node->nodeName,
'text' => &$innerXML,
);
}
// build current innerXML and process children
// check for children
if($node->hasChildNodes()) {
// process children
foreach($node->childNodes as $child) {
// build current innerXML
$innerXML .= $doc->saveXML($child);
// repeat process with children
$out = array_merge($out, $self($child, $skipNonTag));
}
}
// return current + children
return $out;
}
$xml = new DOMDocument();
$xml->load($target_file) or die ("Error: Cannot load xml");
$tags = tagData($xml, true);
//print_r($tags);
?>
I would like to move this data into a MySQL database whose columns match the tags of the file.
你的问题是双重的。
问题的第一部分是对数据库结构做内省。即获取所有table个名字,获取这些的列名。大多数现代数据库都提供此功能,MySQL 也是如此。在 MySQL 中,这些是 INFORMATION_SCHEMA Tables。您可以像查询普通数据库 table 一样查询它们。我通常推荐 PDO 因为 PHP,mysqli 自然也能完美地完成这项工作。
第二部分是解析 XML 数据并将其数据映射到数据库 tables(您使用 SimpleXMLElement因为在你的问题中,所以我与它相关特别是)。为此,您首先需要了解如何将 XML 中的数据映射到数据库中。 XML 文件不像关系数据库 table 那样具有二维结构,但它具有树结构。
例如(如果我没看错你的问题)你将 Message->SettlementReport->SettlementData
识别为第一个 "table" .对于那个 specific 示例,它很容易,因为 <SettlementData>
只有可以表示列名称(元素名称)和值(文本内容)的子元素。为此很容易:
header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $name => $value ) {
echo $name, ': ', $value, "\n";
}
如您所见,在 foreach
子句中指定 key 赋值将为您提供带有 简单XML元素。或者,SimpleXMLElement::getName()
方法做同样的事情(只是一个例子,只是代码略有不同):
header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $value) {
$name = $value->getName();
echo $name, ': ', $value, "\n";
}
在这种情况下,您受益于以下事实:foreach
中提供的 Iterator SimpleXMLElement
您通过 $xml->...->SettlementData
访问遍历所有子元素。
这里的 Xpath 是一个更通用的概念。所以请耐心等待我向您展示第三个示例,它再次执行类似的输出:
header('Content-Type: text/plain; charset=utf-8');
$rows = $xml->xpath('/*/Message/SettlementReport/SettlementData');
foreach ($rows as $row) {
foreach ($row as $column) {
$name = $column->getName();
$value = (string) $column;
echo $name, ': ', $value, "\n";
}
}
然而,如前所述,将树结构(N 深度)映射到二维结构(数据库 table)现在可能总是那么简单。
如果您正在寻找可能的结果(最常见的是数据丢失或数据重复),给出了一个更复杂的PHP示例在之前的问答中:
- How excel reads XML file?
- PHP XML to dynamic table
请注意:事实上,这种映射本身可能很复杂,问题和答案继承自这种复杂性。这首先意味着这些可能不容易阅读,而且 - 或许更突出 - 可能不适用于您的问题。这些只是为了拓宽您的视野,并为某些场景提供一些示例。
希望对您有所帮助,请在下方以评论的形式提供任何反馈。您的问题可能会或可能不会更严重,因此希望这可以帮助您决定 how/where 继续。