Разбор XML с использованием simpleXML

Я пытаюсь разобрать XML, найденный на странице...

http://www.rapleaf.com/apidoc/person

Name: Test Dummy
Age: 42
gender: Male
Address: San Francisco, CA, US
Occupation:
University: Berkeley
first seen: 2006-02-23
last seen: 2008-09-25
Friends: 42
Name:
Age:
gender:
Address:
Occupation:
University:
first seen:
last seen:
Friends: 

1) Пришлось удалить записи, где встречалась "&". Только после этого я смог обработать страницу.

2) Я не смог разобрать «сайт членства» и не смог разобрать «оккупацию».

3) Я получаю 2 записи, когда ожидаю только одну.

4) Как вставить эти записи в базу данных?

<?php

// displays all the file nodes
if(!$xml=simplexml_load_file('rapleaf.xml')){
    trigger_error('Error reading XML file',E_USER_ERROR);
}

foreach($xml as $user){
    echo 'Name: '.$user->name. '
<br /> Age: '.$user->age.'
<br /> gender: '.$user->gender.'
<br /> Address: '.$user->location.'
<br /> Occupation: '.$user->occupations->occupation->company.'
<br /> University: '.$user->universities->university.'
<br /> first seen: '.$user->earliest_known_activity.'
<br /> last seen: '.$user->latest_known_activity.'
<br /> Friends: '.$user->num_friends.'
<br />';
}

?>

person shantanuo    schedule 26.08.2010    source источник
comment
Я думаю, вам лучше разделить этот вопрос на 4 или более вопроса, потому что ответы, которые вы ждете, действительно относятся к разным областям знаний.   -  person mmonem    schedule 30.08.2010
comment
@mmonem: я не согласен. 1-3 - это вопросы, связанные с XML, и имхо, их вполне можно задать в одном вопросе.   -  person fresskoma    schedule 30.08.2010


Ответы (2)


Чтобы иметь возможность разобрать этот документ (который неправильно сформирован), я бы рекомендовал сделать следующее:

$xmlString = file_get_contents('rapleaf.xml');
$xmlString = str_replace('&', '&amp;', $xmlString);

if(!$xml=simplexml_load_string($xmlString)){
    trigger_error('Error reading XML file',E_USER_ERROR);
}

Сначала прочитайте файл в строку, которая заменяет символы амперсанда (внутри ссылки) их сущностью. Что вы можете использовать функцию simplexml_load_file() для создания объекта xml.

Теперь вы можете разобрать документ. Насколько я вижу, в каждом файле есть только один человек. Так что вам не нужен цикл foreach. Но вы можете разобрать все поле, просто нужно знать, как это сделать. Вот более сложный пример, анализирующий разные вещи разными методами:

echo '    Name: '.(string)$xml->basics->name. '
        <br /> Age: '.(string)$xml->basics->age.'
        <br /> gender: '.(string)$xml->basics->gender.'
        <br /> Address: '.(string)$xml->basics->location;
// There might be more than one occupation
foreach($xml->occupations as $occupation){
    echo '<br /> Occupation: '.$occupation->attributes()->title;
    if(isset($occupation->attributes()->company)){
        echo '; at company: '.$occupation->attributes()->company;
    }
}
// There might be more than one university
foreach($xml->universities as $university){
    echo '<br /> University: '.$university;
}
echo    '<br /> first seen: '.(string)$xml->basics->earliest_known_activity.'
        <br /> last seen: '.(string)$xml->basics->latest_known_activity.'
        <br /> Friends: '.(string)$xml->basics->num_friends;
// getting all the primary membership pages
foreach($xml->memberships->primary->membership as $membership){
    if($membership->attributes()->exists == "true"){
        echo '<br />'.$membership->attributes()->site;
        if(isset($membership->attributes()->profile_url)){
            echo ' | '.$membership->attributes()->profile_url;
        }
        if(isset($membership->attributes()->num_friends)){
            echo ' | '.$membership->attributes()->num_friends;
        }
    }
}

Для текста, включенного в тег, вы должны преобразовать его в строку:

echo 'Name: '.(string)$xml->basics->name;

Чтобы получить значение атрибута тега, используйте функцию attribute(). На этот раз вам не нужно разыгрывать его:

echo 'Occupation: '.$xml->occupations->occupation[0]->attributes()->title;

Как видите, вы также можете получить определенный дочерний узел, так как все дочерние узлы хранятся в массиве. Просто используйте индекс. Если вам нужен только один дочерний узел, вам не нужно использовать для этого цикл.

Но вы всегда должны убедиться, что элемент, для которого вы используете функцию attirbutes(), действителен, иначе будет выдана ошибка. Так что, возможно, вы захотите проверить это через isset(), чтобы быть уверенным.

Надеюсь, теперь у вас есть представление о том, как анализировать XML с помощью SimpleXML. Если у вас есть дополнительные вопросы, просто задайте их еще раз или даже в новом вопросе.

person 2ndkauboy    schedule 01.09.2010
comment
Я попробовал код с живыми веб-данными через API и заметил, что имя сайта отображается, даже если выполняется условие exists=false. Не могли бы вы объяснить, почему это происходит? - person shantanuo; 04.09.2010
comment
Я сейчас назвал истинное значение. Проверьте это, может быть проблема. - person 2ndkauboy; 04.09.2010

1 . Амперсанды являются частью спецификации синтаксиса XML (они используются для кодирования нестандартных символов). Следовательно, их нельзя использовать отдельно в документах XML. Они должны быть закодированы в & или заключены в блок CDATA: http://www.w3schools.com/xmL/xml_cdata.asp.

2 . Вы не можете получить доступ к таким дочерним элементам ($user->occupations->occupation), потому что у элемента есть дочерние элементы. Вам нужно будет сделать что-то вроде:

$a = $user->occupations->children();
$b = $b->occupation->attributes();
$c = (string)$b->company;

Проверьте http://php.net/manual/de/book.simplexml.php для получения дополнительной информации.

3 . Вы получаете две записи, потому что элементы XML всегда имеют корневой элемент, который заключает в себе их дочерние элементы. Таким образом, когда вы выполняете итерацию по $xml, вы сначала получаете объект SimpleXMLElement для , а затем для . используется как корневой элемент.

4 . Это действительно другой вопрос, и он зависит от того, какую базу данных вы хотите использовать. Гугл вам в этом поможет. Вы, вероятно, захотите использовать MySQL, потому что вы работаете с php. Так что проверьте http://www.google.de/search?sourceid=chrome&ie=UTF-8&q=php+mysql+tutorial :)

person fresskoma    schedule 30.08.2010