Почему SimpleXMLElement не может найти содержимое файла XML? - PullRequest
0 голосов
/ 27 мая 2018

Мне нужно проанализировать XML-документ, полученный от третьей стороны, с помощью php.Я не могу попросить разработчиков документа исправить его структуру.Когда я анализирую документ, используя simplexml_load_file, документ XML пуст.

Вот упрощенный пример того, что я вижу.

my-file.xml:

<?xml version="1.0" encoding="utf-8"?>
<DataSet>
  <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    aaa
  </diffgr:diffgram>
</DataSet>

И я обрабатываю это так (из командной строки):

php > $xml = simplexml_load_file('my-file.xml');
php > print_r($xml);
SimpleXMLElement Object
(
)

Я ожидал, что структура XML отображается через print_r.

Действительно, когда яудалите объявление пространства имен, кажется, что все работает (несмотря на некоторые ожидаемые предупреждения синтаксического анализа XML):

my-file-nonamespace.xml:

<?xml version="1.0" encoding="utf-8"?>
<DataSet>
  <diffgr:diffgram>
    aaa
  </diffgr:diffgram>
</DataSet>

Обрабатывает его одинаково в командной строке(со снятыми предупреждениями):

php > $xml = simplexml_load_file('my-file-nonamespace.xml');

// a bunch of xml parse warnings
php > print_r($xml);
SimpleXMLElement Object
(
    [diffgr:diffgram] =>
    aaa

)

Итак, проблема связана с неверным объявлением пространства имен.Возможно, я могу использовать регулярное выражение в файле, чтобы удалить объявление пространства имен перед синтаксическим анализом, но это не то направление, в котором я хочу идти.

Каков наилучший способ правильного анализа первого документа в PHP?

1 Ответ

0 голосов
/ 27 мая 2018

Проблема не в том, что данные не загружены, а в том, что дочерние элементы находятся в другом пространстве имен.

$xml = simplexml_load_file('my-file.xml');
var_dump($xml->children("diffgr", true));

Это выбирает дочерние элементы из определенного пространства имен из текущего элемента.

Обратите внимание, что вы должны использовать URI, так как префикс может измениться, но это просто для того, чтобы показать, что данные есть.

Редактировать: Если в XML есть проблемыЗатем на первом этапе игнорируются ошибки, а затем проверяется, что загружено ...

libxml_use_internal_errors(true);
$xml = simplexml_load_file('my-file.xml');
echo $xml->asXML();

Это даст вам представление о том, в каком состоянии находится результат и даже если он загружается.Краткий пример: ...

libxml_use_internal_errors(true);
$xml = simplexml_load_file('my-file.xml');
echo $xml->asXML();
var_dump($xml->children());

С ..

<?xml version="1.0" encoding="utf-8"?>
<DataSet>
  <diffgr:diffgram>
    aaa
  </diffgr:diffgram>
</DataSet>

Обратите внимание на то, как существует пространство имен, но пространство имен не объявлено.Выходные данные ...

<?xml version="1.0" encoding="utf-8"?>
<DataSet>
  <diffgr:diffgram>
    aaa
  </diffgr:diffgram>
</DataSet>
/home/nigel/workspace2/Test/t1.php:22:
class SimpleXMLElement#2 (1) {
  public $diffgr:diffgram =>
  string(11) "
    aaa
  "
}

Это выводит потомков без использования пространства имен.

...