使用SimpleXMLElement从PHP中的XML获取子元素和子元素


Getting child and sub-child elements from XML in PHP with SimpleXMLElement

好吧,一个简单的小任务已经花了我三天的时间!我在OS X 10.6.8上使用PHP,由于各种原因无法升级到Mavericks,所以我没有合适的PHP IDE,只能使用TextWrangler。

这是我的XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<adapt_xml>
<annonce>
    <reference>0001</reference>
    <liste_photos>
        <photo>photo1.jpg</photo>
        <photo>photo2.jpg</photo>
        <photo>photo3.jpg</photo>
        <photo>photo4.jpg</photo>
    </liste_photos>
    <agence>AVENUE RIVIERA</agence>
</annonce>
<annonce>
    <reference>0002</reference>
    <liste_photos>
        <photo>photo1.jpg</photo>
        <photo>photo2.jpg</photo>
        <photo>photo3.jpg</photo>
        <photo>photo4.jpg</photo>
    </liste_photos>
    <agence>AVENUE RIVIERA</agence>
</annonce>
<annonce>
    <reference>0003</reference>
    <liste_photos>
        <photo>photo1.jpg</photo>
        <photo>photo2.jpg</photo>
        <photo>photo3.jpg</photo>
        <photo>photo4.jpg</photo>
    </liste_photos>
    <agence>AVENUE RIVIERA</agence>
</annonce>
</adapt_xml>

我已经找到了如何循环使用annonce元素来提取每个子属性,这样我就可以将它们全部写入我的数据库表annonce:

$xmlFile = simplexml_load_file($file);
foreach($xmlFile->annonce as $annonce)
{
    foreach($annonce->children() as $child)
    {
        ...
        echo $child->getName().": ".(string)$child."<br />";
    }
}

我希望能够循环浏览照片,恢复每张照片以及对公告的引用(关系照片对公告是多对一的)。当我将代码插入foreach($annonce->children() as $child)空间时,照片上什么都没有显示:

$xmlFile = simplexml_load_file($file);
foreach($xmlFile->annonce as $annonce)
{
    foreach($annonce->children() as $child)
    {
        ...
        echo $child->getName().": ".(string)$child."<br />";
        foreach ($child->{"liste_photos"} as $liste_photos)
        {
            foreach ($liste_photos->{"photo"} as $photo)
            {
                ...
                echo $photo->getName().": ".(string)$photo."<br />";
            }
        }
    }
}

我做错了什么??

此时此刻不需要大括号。根据我的经验。

foreach($xmlFile->annonce as $annonce)
{
    foreach($annonce->liste_photos as $liste_photos)
    {
        foreach ($liste_photos->photo as $photo)
        {
                ...
                echo $photo->getName().": ".(string)$photo."<br />";
        }
    }
}

脚本的问题是在与<liste_photos>处于同一级别的XML元素上调用$child->liste_photos,包括<liste_photos>本身。您需要在父元素<annonce>(脚本中的$annonce)上调用它,因为<liste_photos><annonce>的子元素。

由于您使用的是simpleXML,并且您知道XML的结构,因此通过使用以下元素名称访问元素,您可以让自己的生活更加轻松:

foreach($xmlFile->annonce as $annonce) {
    $ref = $annonce->reference;
    echo "reference: " . $annonce->reference . PHP_EOL;
    echo "agence: " . $annonce->agence . PHP_EOL;
    foreach ($annonce->liste_photos->photo as $photo) {
        echo "photo: " . $photo . "; reference: $ref" . PHP_EOL;
    }
}

XML的输出:

reference: 0001
agence: AVENUE RIVIERA
photo: photo1.jpg; reference: 0001
photo: photo2.jpg; reference: 0001
photo: photo3.jpg; reference: 0001
photo: photo4.jpg; reference: 0001
reference: 0002
agence: AVENUE RIVIERA
photo: photo1.jpg; reference: 0002
photo: photo2.jpg; reference: 0002
photo: photo3.jpg; reference: 0002
photo: photo4.jpg; reference: 0002
reference: 0003
agence: AVENUE RIVIERA
photo: photo1.jpg; reference: 0003
photo: photo2.jpg; reference: 0003
photo: photo3.jpg; reference: 0003
photo: photo4.jpg; reference: 0003

关于:在simpleXML中,在子元素的名称周围使用大括号,就像您在这里所做的那样:

foreach ($child->{"liste_photos"} as $liste_photos)
{
    foreach ($liste_photos->{"photo"} as $photo)

大括号是不必要的,除非XML元素名称中有一个字符会导致PHP误解它;对于大多数XML文档,唯一会引起问题的字符是连字符(例如,如果您有$child->{'liste-photos'})。PHP可以正确地解释下划线,因此不需要大括号。