我试图读取XML文件中的键和值,该文件首先创建为对象,然后尝试在foreach循环中进行迭代。 我的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">10</int><lst name="params"><str name="q">*:*</str><str name="facet.field">main</str><str name="facet.mincount">1</str><str name="rows">0</str><str name="facet">on</str></lst></lst><result name="response" numFound="5473" start="0"/><lst name="facet_counts"><lst name="facet_queries"/><lst name="facet_fields"><lst name="main"><int name="Victoria University Photograph Collection">1693</int>
......
我的php代码是:
foreach($input as $int){
echo $int->response->int;
$arr = array();
foreach ($int as $key => $value){
$arr[(string)$key]=(string)$value;
}
$arr[]=$arr;
}
print_r($arr);
echo行不显示任何内容,并且数组仅显示不具有任何值的xml内容。因此,它仅打印[lst]。我需要在标记内检索名称和值。
谢谢。
答案 0 :(得分:1)
您可以使用xpath表达式来获取int
元素内lst
元素的名称和值。
如果要使用名称作为键将它们放在数组中,则可以使用多维数组,其中键值位于其自己的数组中,因为当xml中的名称相同时,键使用一维数组将被覆盖。
$items = $input->xpath('/response/lst/int');
$arr = [];
foreach ($items as $item) {
if (isset($item->attributes()->name) && trim((string)$item) !== "") {
$arr[] = [(string)$item->attributes()->name => (string)$item];
}
}
print_r($arr);
或者获取int
标记内的所有名称和值:
$items = $input->xpath('/response/lst//*');
$arr = [];
foreach ($items as $item) {
if (isset($item->attributes()->name) && trim((string)$item) !== "") {
$arr[] = [(string)$item->attributes()->name => (string)$item];
}
}
print_r($arr);
答案 1 :(得分:0)
阅读SimpleXML的PHP手册: http://php.net/manual/en/book.simplexml.php
此外,您的XML格式不正确,您将相同的元素名称用于不同的值。元素名称应指定值。
答案 2 :(得分:0)
我已将您的XML重新格式化以提高可读性(内容未经修改)。看起来您只在问题中发布了XML的一部分,因为最后遗漏了几个</lst>
结束标记,并且也错过了</response>
结束标记:
$xml = '
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">10</int>
<lst name="params">
<str name="q">*:*</str>
<str name="facet.field">main</str>
<str name="facet.mincount">1</str>
<str name="rows">0</str>
<str name="facet">on</str>
</lst>
</lst>
<result name="response" numFound="5473" start="0"/>
<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields">
<lst name="main">
<int name="Victoria University Photograph Collection">1693</int>
</lst>' /* added by me */ . '
</lst>' /* added by me */ . '
</lst>' /* added by me */ . '
</response>' /* added by me */ . '
';
$input = simplexml_load_string($xml);
在您的情况下<response>
,SimpleXML将返回对根元素的引用。如您所见,在示例代码中,此<response>
元素包含两个<lst>
子级和一个<result>
子级。这意味着$input->lst
将是一个包含两个条目的数组:两个<lst>
元素,按照它们在文档中出现的顺序。
您的代码正在专门寻找<int>
元素作为某事物的第一个子元素,这似乎只是第一个<lst>
元素的情况。第二个<lst>
元素中还有一个元素,但是该元素隐藏在depper级别上,因此我现在将其略过。因此,基本上,我们需要在<int>
中寻找$input->lst[0]
。
$arr = array();
foreach ($input->lst[0]->int as $int) {
// get the name from the attributes
$name = (string)$int['name'];
// get the element's text content
$value = (string)$int;
$arr[$name] = $value;
}
print_r($arr);
如果您要搜索所有(顶级)<lst>
,则需要一个额外的循环:
$arr = array();
foreach ($input->lst as $lst) {
foreach ($lst->int as $int) {
$name = (string)$int['name'];
$value = (string)$int;
$arr[$name] = $value;
}
}
print_r($arr);
在您的示例代码中,这两种情况都输出以下数组(因为第二个<int>
中的<lst>
被埋得更深了):
Array
(
[status] => 0
[QTime] => 10
)
现在,如果您想遍历任何嵌套的<lst>
,不管它有多深,您都可以考虑使用它来创建递归函数:
function parseLst($lst, &$arr) {
// note the & before $arr, this is necessary to make `$arr[$name] = $value;` work.
// Another option would be to use `global $arr;` and not pass it as an argument,
// or if you're doing this in a class, to use `$this->arr` instead.
foreach ($lst->int as $int) {
$name = (string)$int['name'];
$value = (string)$int;
$arr[$name] = $value;
}
foreach ($lst->lst as $childLst) {
parseLst($childLst, $arr);
}
};
$arr = array();
foreach ($input->lst as $lst) {
parseLst($lst, $arr);
}
print_r($arr);
这将产生:
Array
(
[status] => 0
[QTime] => 10
[Victoria University Photograph Collection] => 1693
)