[英]Iterating through XML file with php
我有一個包含以下內容的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>
我可以遍歷文件並獲取除圖像URL之外的值。 我正在為具有屬性的元素在元素之后苦苦掙扎。
$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++;
}
但是第二個循環並不太正確。 我將不勝感激一些幫助。
大概是這樣的:
foreach($xml->property[$count]->images as $image) {
echo $image->url;
}
您尚未共享完整的XML結構,因此尚不清楚文檔根目錄(文檔元素)在哪里。
假設根元素不是<property>
但所有<property>
元素都是root元素的子元素,則可以通過僅對它們進行迭代來遍歷所有這些<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
變量。 可以,但是不需要。 只是說。
現在,您正在尋找圖像URL。 每個<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手冊中有一些更棒的材料,名為“ 基本SimpleXML用法” ,它顯示了基本遍歷並還鏈接到更高級的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不能具有私有屬性(因為這些屬性都是魔術),但是您可以創建靜態全局變量。 為了保留音譯器的實例,這就足夠了。 為了處理字符串值, __toString()
魔術方法與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);
}
}
但是輸出將把“ Schloß
”變成“ schloss
”,“ tôwn
”變成“ town
”,“ provincé
”變成“ province
”。
Transliterator需要PHP 5.4,並且您已啟用了Intl擴展 (如果未啟用,則應具有)。
或者,您也可以使用iconv庫中的音譯 。 但是請注意,這會產生稍微不同的輸出:
$transliterated = iconv('UTF-8', 'ASCII//IGNORE//TRANSLIT', $this);
更多相關的音譯問題:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.