PHP справляется с отсутствующими данными XML - PullRequest
3 голосов
/ 03 июня 2011

Если у меня есть три набора данных, скажем:

<note><from>Me</from><to>someone</to><message>hello</message></note>

<note><from>Me</from><to></to><message>Need milk & eggs</message></note>

<note><from>Me</from><message>Need milk & eggs</message></note>

и я использую simplexml, есть ли способ сделать простую проверку xml на наличие пустого / отсутствующего тега автоматически?

Я бы хотел, чтобы результат был:

FROM    TO     MESSAGE
Me    someone    hello
Me    NULL    Need milk & eggs
Me    NULL    Need milk & eggs

Прямо сейчас я делаю это вручную, и я быстро понял, что это займет очень много времени, чтобы сделать это для длинных XML-файлов.

Мой текущий пример кода:

$xml = simplexml_load_string($string);
if ($xml->from != "") {$out .= $xml->from."\t"} else {$out .= "NULL\t";}
//repeat for all children, checking by name

Иногда порядок также отличается, может быть XML с:

<note><message>pick up cd</message><from>me</from></note>

поэтому итерации по дочерним элементам и проверка по количеству индексов не работают.

Фактические xml-файлы, с которыми я работаю, имеют тысячи строк каждый, поэтому я, очевидно, не могу просто кодировать каждый тег.

Ответы [ 2 ]

2 голосов
/ 03 июня 2011

Похоже, вам нужен DTD (определение типа документа), который определит требуемый формат файла XML и определит, какие элементы являются обязательными, необязательными, что они могут содержать и т. Д.

DTDможет использоваться для проверки XML-файла перед выполнением какой-либо обработки с ним.

К сожалению, библиотека simplexml в PHP ничего не делает с DTD, но библиотека DomDocument делает, поэтому вы можете использовать это вместо этого.

Я оставлю вам отдельное упражнение для изучения того, как создать файл DTD.Если вам нужна дополнительная помощь, я бы предложил задать это как отдельный вопрос.

1 голос
/ 03 июня 2011

Вместо этого вы можете использовать DOMDocument .Я создал быструю демонстрацию, которая разбивает элементы <note> на массив, используя имена тегов XML как keys .Затем можно выполнить итерацию результирующего массива для создания выходных данных.

Я исправил недопустимый XML, заменив амперсанд на эквивалентный объект HTML (&amp;).

<?php
    libxml_use_internal_errors(true);
    $xml = <<<XML
<notes>
<note><from>Me</from><to>someone</to><message>hello</message></note>
<note><from>Me</from><to></to><message>Need milk &amp; eggs</message></note>
<note><from>Me</from><message>Need milk &amp; eggs</message></note>
<note><message>pick up cd</message><from>me</from></note>
</notes>
XML;

    function getNotes($nodelist) {
        $notes = array();

        foreach ($nodelist as $node) {
            $noteParts = array();

            foreach ($node->childNodes as $child) {
                $noteParts[$child->tagName] = $child->nodeValue;
            }

            $notes[] = $noteParts;
        }

        return $notes;
    }

    $dom = new DOMDocument();
    $dom->recover = true;
    $dom->loadXML($xml);
    $xpath = new DOMXPath($dom);
    $nodelist = $xpath->query("//note");
    $notes = getNotes($nodelist);

    print_r($notes);
?>

Изменить: Если вы измените на $noteParts = array(); на $noteParts = array('from' => null, 'to' => null, 'message' => null);, то он всегда будет создавать полный набор ключей .

...