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

时间:2014-10-25 19:19:36

标签: php xml simplexml

好的,应该是一个简单的小任务已经花了我三天!我在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 />";
    }
}

想要能够做的是循环拍摄照片,恢复每张照片以及对annonce的参照物(与annonce的关系照片是多对一的)。当我将代码插入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 />";
            }
        }
    }
}

我做错了什么?

2 个答案:

答案 0 :(得分:2)

你不应该在这一瞬间需要牙箍。根据我的经验。

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

答案 1 :(得分:1)

您的脚本存在的问题是,您在与$child->liste_photos处于同一级别的XML元素上调用<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

Re:在simpleXML中使用大括号名称的大括号,就像你在这里做的那样:

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

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