我有一个包含以下内容的XML文件:
<property>
<id>1</id>
<type>type</type>
<town>town</town>
<province>province</province>
<images>
<image id="1">
<url>
http://www.test.com
</url>
<image id="2">
<url>
http://www.test.com
</url>
<image id="3">
<url>
http://www.test.com
</url>
</image>
我可以遍历文件并获取除图像网址之外的值。 我正在为具有属性的元素之后的元素进行挣扎。
$count=0;
$id=0;
foreach($xml->children() as $properties) {
echo "<h1>" . $xml->property[$count]->type . " for sale in " .$xml->property[$count]->town . ", " . $xml->property[$count]->province . "</h1>" . "<br>";
echo $xml->property[$count]->id . "<br>";
echo $xml->property[$count]->desc->en . "<br>";
foreach($xml->property[$count]->children() as $images) {
echo $xml->property[$count]->images -> image[$id++] -> url;
$id++;
}
$count++;
}
但是第二个循环并不接近正确。 我非常感谢一些帮助。
答案 0 :(得分:0)
或许这样的事情:
foreach($xml->property[$count]->images as $image) {
echo $image->url;
}
答案 1 :(得分:0)
您尚未共享完整的XML结构,因此不清楚文档的根目录(文档元素)。
假设根元素不是<property>
但是所有<property>
元素都是根元素的子元素,您只需迭代它们就可以迭代所有<property>
元素:
$xml = simplexml_load_file('example.xml');
foreach ($xml->property as $property) {
printf(
"<h1>%s for sale in %s, %s</h1>\n", htmlspecialchars($property->id),
htmlspecialchars($property->town), htmlspecialchars($property->province)
);
如您所见,您不需要明确地使用$count
变量。你可以,但你不需要。只是说。
现在您正在寻找图片网址。每个<property>
元素都有一个名为<images>
的子元素,这些元素同样具有您感兴趣的多个<url>
元素。
这可以通过xpath查询来完成(当您深入到多个级别时):
$urls = $property->xpath('images/image/url');
foreach ($urls as $url) {
printf(" - %s\n", htmlspecialchars(trim($url)));
}
如果您不在此处使用xpath,则需要为包含多个子级的每个级别创建一个foreach。就像一个反例:
foreach ($property->images->image as $image) {
foreach ($image->url as $url) {
printf(" - %s\n", htmlspecialchars(trim($url)));
}
}
我希望这能更好地告诉你如何在simplexml中进行遍历。 PHP手册中有一些更好的材料,标题为Basic SimpleXML usage,它显示了基本的遍历,还链接到更高级的xpath主题。
当您将动态数据输出到HTML以对其进行正确的HTML编码时,请不要忘记。我已经使用了htmlspecialchars
函数,您需要提供正确的编码参数,我在答案中为了简洁而遗漏了这些参数。
完整示例:
<?php
/**
* @link https://stackoverflow.com/questions/28929239/iterating-through-xml-file-with-php
*/
$buffer = <<<XML
<root>
<property>
<id>1</id>
<type>type</type>
<town>town</town>
<province>province</province>
<images>
<image id="1">
<url>
http://www.test.com
</url>
</image>
<image id="2">
<url>
http://www.test.com
</url>
</image>
<image id="3">
<url>
http://www.test.com
</url>
</image>
</images>
</property>
<property>
<id>1</id>
<images>
<image id="1">
<url>
http://www.test.com
</url>
</image>
</images>
</property>
</root>
XML;
$xml = simplexml_load_string($buffer);
foreach ($xml->property as $property) {
printf(
"<h1>%s for sale in %s, %s</h1>\n",
htmlspecialchars($property->id), htmlspecialchars($property->town), htmlspecialchars($property->province)
);
$urls = $property->xpath('images/image/url');
foreach ($urls as $url) {
printf(" - %s\n", htmlspecialchars(trim($url)));
}
}
示例性输出(纯文本):
<h1>1 for sale in town, province</h1>
- http://www.test.com
- http://www.test.com
- http://www.test.com
<h1>1 for sale in , </h1>
- http://www.test.com
通过扩展 SimpleXMLElement 的每个字符串值,可以实现全局应用音译(删除重音)和HTML编码(htmlspecialchars
)的一种方法。有一个简短的说法: SimpleXMLElement 不能拥有私有属性(因为这些属性都很神奇),但是您可以创建静态全局变量。为了保持Transliterator的实例,这就足够了。对于操纵字符串值,__toString()
magic method适用于 SimpleXMLElement :
/**
* Transliterate and HTML encode
*
* Class XMLTransliterated
*/
class XMLTransliterated extends SimpleXMLElement
{
public static $transliterator;
public function __toString()
{
$transliterator = &self::$transliterator;
$transliterator || $transliterator = Transliterator::create("Latin-ASCII");
$transliterated = $transliterator->transliterate($this);
return htmlspecialchars(trim($transliterated), ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
}
在创建 SimpleXMLElement 时,您需要做的就是使用字符串操作来使用此类名XMLTransliterated
(或任何您命名的类):
$xml = simplexml_load_string($buffer, 'XMLTransliterated');
- 或 - 这对于simplexml来说非常特殊,你可以稍后用一点转换技巧改变这个类:
$xml = simplexml_import_dom(dom_import_simplexml($xml), 'XMLTransliterated');
这将使以下代码使用 XMLTransliterated 而不是之前不太具体的 SimpleXMLElement ,因此代码基本保持不变(请注意htmlspecialchars
并且trim
调用可以安全删除,因为它们在访问 SimpleXMLElement 的字符串值时会自动调用:
$xml = simplexml_load_string($buffer, 'XMLTransliterated');
foreach ($xml->property as $property) {
printf(
"<h1>%s (%s) for sale in %s, %s</h1>\n",
$property->id, $property->type, $property->town, $property->province
);
$urls = $property->xpath('images/image/url');
foreach ($urls as $url) {
printf(" - %s\n", $url);
}
}
但输出会变成&#34; Schloß
&#34;进入&#34; schloss
&#34;,&#34; tôwn
&#34;进入&#34; town
&#34;和&#34; provincé
&#34;进入&#34; province
&#34;。
Transliterator 需要PHP 5.4并且启用了Intl extension(如果没有启用它,您应该拥有它)。
或者您也可以使用transliteration from the iconv library。但请注意,这会产生略微不同的输出:
$transliterated = iconv('UTF-8', 'ASCII//IGNORE//TRANSLIT', $this);
更多相关音译问题: