У меня есть документ XML со следующей структурой:PHP XML Expat parser: как читать только часть документа XML?
<posts>
<user id="1222334">
<post>
<message>hello</message>
<client>client</client>
<time>time</time>
</post>
<post>
<message>hello client how can I help?</message>
<client>operator</client>
<time>time</time>
</post>
</user>
<user id="2333343">
<post>
<message>good morning</message>
<client>client</client>
<time>time</time>
</post>
<post>
<message>good morning how can I help?</message>
<client>operator</client>
<time>time</time>
</post>
</user>
</posts>
Я могу создать парсер и распечатать весь документ, проблема в том, однако, что я хочу, чтобы напечатать только (пользователь) узел и ребенок с определенным атрибутом (id).
мой PHP код:
if(!empty($_GET['id'])){
$id = $_GET['id'];
$parser=xml_parser_create();
function start($parser,$element_name,$element_attrs)
{
switch($element_name)
{
case "USER": echo "-- User --<br>";
break;
case "CLIENT": echo "Name: ";
break;
case "MESSAGE": echo "Message: ";
break;
case "TIME": echo "Time: ";
break;
case "POST": echo "--Post<br> ";
}
}
function stop($parser,$element_name){ echo "<br>"; }
function char($parser,$data){ echo $data; }
xml_set_element_handler($parser,"start","stop");
xml_set_character_data_handler($parser,"char");
$file = "test.xml";
$fp = fopen($file, "r");
while ($data=fread($fp, filesize($file)))
{
xml_parse($parser,$data,feof($fp)) or
die (sprintf("XML Error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
xml_parser_free($parser);
}
используя это в функции start()
может выбрать правильный узел, но это не оказывает никакого влияния на процесс чтения:
if(($element_name == "USER") && $element_attrs["ID"] && ($element_attrs["ID"] == "$id"))
любая помощь оцениваться
ОБНОВЛЕНИЕ: XMLReader работает, но при использовании оператора if он останавливается работая:
foreach ($filteredUsers as $user) {
echo "<table border='1'>";
foreach ($user->getChildElements('post') as $index => $post) {
if($post->getChildElements('client') == "operator"){
printf("<tr><td class='blue'>%s</td><td class='grey'>%s</td></tr>", $post->getChildElements('message'), $post->getChildElements('time'));
}else{
printf("<tr><td class='green'>%s</td><td class='grey'>%s</td></tr>", $post->getChildElements('message'), $post->getChildElements('time'));
}
}
echo "</table>";
}
Можно ли использовать ['XMLReader'] (http://php.net/book.xmlreader) вместо парсера expat? – hakre
Я предпочитаю использовать парсер Expat, он является родным для PHP и может обрабатывать большие XML-файлы, это также основанный на события парсер, а не DOM. Я нахожу его очень мощным, и мне особенно нравится функция 'xml_set_element_handler', которая помогает легко определять начальный и конечный теги. я уверен, что должна быть возможность прочитать часть документа! – razzak
'XMLReader' является родным для PHP и может обрабатывать большие XML-файлы, это парсер XML Pull. Читатель действует как курсор, идущий вперед по потоку документа и останавливаясь на каждом узле по пути. И для Expat: Нет, такого варианта нет, но для XMLReader есть;) Вот почему я спрашиваю. – hakre