使用 SimpleXML 和 XPath 遍历 XML,结果顺序错误
Iterating through XML with SimpleXML and XPath, Result is in wrong order
我的variables.php
$xmlFile = 'xml.xml';
$xmlFileLoad = simplexml_load_file($xmlFile);
$xmlFileLoad->registerXPathNamespace("oi", "http://www.openimmo.de");
$immobilie = $xmlFileLoad->xpath('//oi:immobilie');
$zustand_angaben_letztemodernisierung = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:letztemodernisierung');
$zustand_angaben_zustand = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:zustand/@zustand_art');
$zustand_angaben_alter = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:alter/@alter_attr');
$zustand_angaben_erschliessung = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:erschliessung/@erschl_attr');
$zustand_angaben_altlasten = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:altlasten');
$zustand_angaben_baujahr = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:baujahr');
xml 文件(缩略版)
<?xml version="1.0" encoding="utf-8"?>
<openimmo xmlns="http://www.openimmo.de"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openimmo.de openimmo.xsd">
<immobilie>
<zustand_angaben>
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<baujahr>ca. 1900</baujahr>
<altlasten>nein</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<baujahr>ca. 1989</baujahr>
<zustand zustand_art="ERSTBEZUG" />
<alter alter_attr="ALTBAU" />
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
</openimmo>
我的show.php
<?php
include("variables.php");
$i = 0;
foreach ($immobilie as $immo) {
echo "Immobilie $i<br />";
if(isset($zustand_angaben_zustand[$i])) {
echo $zustand_angaben_zustand[$i] . "</br>";
}
if(isset($zustand_angaben_alter[$i])) {
echo $zustand_angaben_alter[$i] . "</br>";
}
if(isset($zustand_angaben_erschliessung[$i])) {
echo $zustand_angaben_erschliessung[$i] . "</br>";
}
if(isset($zustand_angaben_altlasten[$i])) {
echo $zustand_angaben_altlasten[$i] . "</br>";
}
if(isset($zustand_angaben_baujahr[$i])) {
echo $zustand_angaben_baujahr[$i] . "</br>";
}
echo "<br /><br />";
$i++;
}
?>
当我执行代码时,结果如下
Immobilie 0
ERSTBEZUG
ALTBAU
keine
5
A
5
A++
ca. 1900
Immobilie 1
keine
ca. 1989
Immobilie 2
keine
Immobilie 3
nein
Immobilie 4
keine
但我希望它按 xml 中的顺序排列,所以 Immobilie 0 只有 keine,Immobilie 1 和 2,第三个 1900 和 nein,最后但并非最不重要的 Immobilie 4 具有所有属性在 xml...
我做错了什么?
改用相对于当前 immobilie
元素的 XPath 表达式:
$i = 0;
foreach ($immobilie as $immo) {
$immo->registerXPathNamespace("oi", "http://www.openimmo.de");
$zustand_angaben_letztemodernisierung = $immo->xpath('./oi:zustand_angaben/oi:letztemodernisierung');
$zustand_angaben_zustand = $immo->xpath('./oi:zustand_angaben/oi:zustand/@zustand_art');
$zustand_angaben_alter = $immo->xpath('./oi:zustand_angaben/oi:alter/@alter_attr');
$zustand_angaben_erschliessung = $immo->xpath('./oi:zustand_angaben/oi:erschliessung/@erschl_attr');
$zustand_angaben_altlasten = $immo->xpath('./oi:zustand_angaben/oi:altlasten');
$zustand_angaben_baujahr = $immo->xpath('./oi:zustand_angaben/oi:baujahr');
echo "Immobilie $i<br />";
if(isset($zustand_angaben_zustand[0])) {
echo $zustand_angaben_zustand[0] . "</br>";
}
if(isset($zustand_angaben_alter[0])) {
echo $zustand_angaben_alter[0] . "</br>";
}
if(isset($zustand_angaben_erschliessung[0])) {
echo $zustand_angaben_erschliessung[0] . "</br>";
}
if(isset($zustand_angaben_altlasten[0])) {
echo $zustand_angaben_altlasten[0] . "</br>";
}
if(isset($zustand_angaben_baujahr[0])) {
echo $zustand_angaben_baujahr[0] . "</br>";
}
echo "<br /><br />";
$i++;
}
当您 运行 xpath 并行查询时,它们的所有顺序彼此相邻。
对于您的具体示例,您实际上并不需要 xpath,该文档看起来非常适合 SimpleXMLElement,您可以检索数据直接来自它。
如果你遍历你感兴趣的对象(这里很可能是 each immobilie 元素)然后提取数据(过滤掉未设置的元素),它可以像下面的例子一样工作:
$xml = simplexml_load_string($string);
foreach ($xml->immobilie as $immobilie) {
$angaben = $immobilie->zustand_angaben;
$data = [
'letzte_modernisierung' => $angaben->letztemodernisierung,
'zustand_art' => $angaben->zustand['zustand_art'],
'alter' => $angaben->alter['alter_attr'],
'erschliessung' => $angaben->erschliessung['erschl_attr'],
'altlasten' => $angaben->altlasten,
'baujahr' => $angaben->baujahr,
];
echo " * Immobilie:\n";
foreach(array_filter($data) as $label => $wert) {
echo " - $label: $wert\n";
}
}
输出是(也:online-demo):
* Immobilie:
- altlasten: keine
* Immobilie:
- altlasten: keine
* Immobilie:
- altlasten: keine
* Immobilie:
- altlasten: nein
- baujahr: ca. 1900
* Immobilie:
- zustand_art: ERSTBEZUG
- alter: ALTBAU
- altlasten: keine
- baujahr: ca. 1989
Xpath 一点也不差,对于像你这里这样的场景,我建议你使用 DOMDocument 而不是 SimpleXMLElement 由于 evaluate 方法 DOMXpath has.
,它在 Xpath 中更加灵活
在任何情况下,您都可以进一步阅读这个显示一个 DOMDocument 和一个 SimpleXMLElement 的问题基于 Xpath 的数据检索解决方案来自 XML 个文档:
我的variables.php
$xmlFile = 'xml.xml';
$xmlFileLoad = simplexml_load_file($xmlFile);
$xmlFileLoad->registerXPathNamespace("oi", "http://www.openimmo.de");
$immobilie = $xmlFileLoad->xpath('//oi:immobilie');
$zustand_angaben_letztemodernisierung = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:letztemodernisierung');
$zustand_angaben_zustand = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:zustand/@zustand_art');
$zustand_angaben_alter = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:alter/@alter_attr');
$zustand_angaben_erschliessung = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:erschliessung/@erschl_attr');
$zustand_angaben_altlasten = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:altlasten');
$zustand_angaben_baujahr = $xmlFileLoad->xpath('/oi:openimmo/oi:immobilie/oi:zustand_angaben/oi:baujahr');
xml 文件(缩略版)
<?xml version="1.0" encoding="utf-8"?>
<openimmo xmlns="http://www.openimmo.de"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openimmo.de openimmo.xsd">
<immobilie>
<zustand_angaben>
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<baujahr>ca. 1900</baujahr>
<altlasten>nein</altlasten>
</zustand_angaben>
</immobilie>
<immobilie>
<zustand_angaben>
<baujahr>ca. 1989</baujahr>
<zustand zustand_art="ERSTBEZUG" />
<alter alter_attr="ALTBAU" />
<altlasten>keine</altlasten>
</zustand_angaben>
</immobilie>
</openimmo>
我的show.php
<?php
include("variables.php");
$i = 0;
foreach ($immobilie as $immo) {
echo "Immobilie $i<br />";
if(isset($zustand_angaben_zustand[$i])) {
echo $zustand_angaben_zustand[$i] . "</br>";
}
if(isset($zustand_angaben_alter[$i])) {
echo $zustand_angaben_alter[$i] . "</br>";
}
if(isset($zustand_angaben_erschliessung[$i])) {
echo $zustand_angaben_erschliessung[$i] . "</br>";
}
if(isset($zustand_angaben_altlasten[$i])) {
echo $zustand_angaben_altlasten[$i] . "</br>";
}
if(isset($zustand_angaben_baujahr[$i])) {
echo $zustand_angaben_baujahr[$i] . "</br>";
}
echo "<br /><br />";
$i++;
}
?>
当我执行代码时,结果如下
Immobilie 0
ERSTBEZUG
ALTBAU
keine
5
A
5
A++
ca. 1900
Immobilie 1
keine
ca. 1989
Immobilie 2
keine
Immobilie 3
nein
Immobilie 4
keine
但我希望它按 xml 中的顺序排列,所以 Immobilie 0 只有 keine,Immobilie 1 和 2,第三个 1900 和 nein,最后但并非最不重要的 Immobilie 4 具有所有属性在 xml...
我做错了什么?
改用相对于当前 immobilie
元素的 XPath 表达式:
$i = 0;
foreach ($immobilie as $immo) {
$immo->registerXPathNamespace("oi", "http://www.openimmo.de");
$zustand_angaben_letztemodernisierung = $immo->xpath('./oi:zustand_angaben/oi:letztemodernisierung');
$zustand_angaben_zustand = $immo->xpath('./oi:zustand_angaben/oi:zustand/@zustand_art');
$zustand_angaben_alter = $immo->xpath('./oi:zustand_angaben/oi:alter/@alter_attr');
$zustand_angaben_erschliessung = $immo->xpath('./oi:zustand_angaben/oi:erschliessung/@erschl_attr');
$zustand_angaben_altlasten = $immo->xpath('./oi:zustand_angaben/oi:altlasten');
$zustand_angaben_baujahr = $immo->xpath('./oi:zustand_angaben/oi:baujahr');
echo "Immobilie $i<br />";
if(isset($zustand_angaben_zustand[0])) {
echo $zustand_angaben_zustand[0] . "</br>";
}
if(isset($zustand_angaben_alter[0])) {
echo $zustand_angaben_alter[0] . "</br>";
}
if(isset($zustand_angaben_erschliessung[0])) {
echo $zustand_angaben_erschliessung[0] . "</br>";
}
if(isset($zustand_angaben_altlasten[0])) {
echo $zustand_angaben_altlasten[0] . "</br>";
}
if(isset($zustand_angaben_baujahr[0])) {
echo $zustand_angaben_baujahr[0] . "</br>";
}
echo "<br /><br />";
$i++;
}
当您 运行 xpath 并行查询时,它们的所有顺序彼此相邻。
对于您的具体示例,您实际上并不需要 xpath,该文档看起来非常适合 SimpleXMLElement,您可以检索数据直接来自它。
如果你遍历你感兴趣的对象(这里很可能是 each immobilie 元素)然后提取数据(过滤掉未设置的元素),它可以像下面的例子一样工作:
$xml = simplexml_load_string($string);
foreach ($xml->immobilie as $immobilie) {
$angaben = $immobilie->zustand_angaben;
$data = [
'letzte_modernisierung' => $angaben->letztemodernisierung,
'zustand_art' => $angaben->zustand['zustand_art'],
'alter' => $angaben->alter['alter_attr'],
'erschliessung' => $angaben->erschliessung['erschl_attr'],
'altlasten' => $angaben->altlasten,
'baujahr' => $angaben->baujahr,
];
echo " * Immobilie:\n";
foreach(array_filter($data) as $label => $wert) {
echo " - $label: $wert\n";
}
}
输出是(也:online-demo):
* Immobilie:
- altlasten: keine
* Immobilie:
- altlasten: keine
* Immobilie:
- altlasten: keine
* Immobilie:
- altlasten: nein
- baujahr: ca. 1900
* Immobilie:
- zustand_art: ERSTBEZUG
- alter: ALTBAU
- altlasten: keine
- baujahr: ca. 1989
Xpath 一点也不差,对于像你这里这样的场景,我建议你使用 DOMDocument 而不是 SimpleXMLElement 由于 evaluate 方法 DOMXpath has.
,它在 Xpath 中更加灵活在任何情况下,您都可以进一步阅读这个显示一个 DOMDocument 和一个 SimpleXMLElement 的问题基于 Xpath 的数据检索解决方案来自 XML 个文档: