Обнаруживать теги самоподключения XML с помощью PHP XMLReader

Я хотел бы проанализировать один XML-документ с помощью XMLReader. У меня есть переключатель случая со всеми Константами. Однако, если тег самозакрывающийся XMLReader запускает только ELEMENT, а не ELEMENT и END_ELEMENT, как ожидалось.

Обнаружение через свойство класса $ isEmptyElement также не работает, потому что тег имеет атрибуты.

Поэтому мой вопрос: как обнаружить самозакрывающийся тег XML с XMLReader в PHP?

Связанное, но без решения: XmlReader – элемент Self-clos не запускает событие EndElement?

Пример узла:

<mynode name="somenamestring" code="intstring" option="intstring3"/> 

Мой код:

 $xmlReader->open($url,NULL); $xmlWriter = new XMLWriter(); $xmlWriter->openMemory(); $xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->setIndent(true); $xmlWriter->setIndentString(' '); while ($xmlReader->read()) { switch ($xmlReader->nodeType) { case 1: #element $xmlWriter->startElement($xmlReader->name); if ($xmlReader->hasAttributes) { while ($xmlReader->moveToNextAttribute()) { $xmlWriter->writeAttribute($xmlReader->name,$xmlReader->value); } } if ($xmlReader->isEmptyElement) { $xmlWriter->endElement(); } break; case 3: #text $xmlWriter->text($xmlReader->value); break; case 4: #cdata $xmlWriter->writeCData($xmlReader->value); break; case 14: #whitespace break; case 15: #end element $xmlWriter->endElement(); break; default: print('[WARN] NodeType not in case-switch: '.(string)$xmlReader->nodeType."\n"); break; } } 

Обнаружение через свойство класса $ isEmptyElement также не работает, потому что тег имеет атрибуты.

Это просто неправильно. Пустой элемент с атрибутами по-прежнему пуст, и $isEmptyElement это отразит. Проблема с вашим кодом заключается в том, что вы проверяете $isEmptyElement после перехода к атрибутам. Это изменит текущий узел на узел атрибута, который не является пустым элементом. Должно работать следующее:

  $isEmpty = $xmlReader->isEmptyElement; if ($xmlReader->hasAttributes) { while ($xmlReader->moveToNextAttribute()) { ... } } if ($isEmpty) { $xmlWriter->endElement(); } 

Или, альтернативно:

  if ($xmlReader->hasAttributes) { while ($xmlReader->moveToNextAttribute()) { ... } $xmlReader->moveToElement(); } if ($xmlReader->isEmptyElement) { $xmlWriter->endElement(); }