Я хотел бы проанализировать один XML-документ с использованием XMLReader. У меня есть переключатель дел со всеми константами. Однако, если тег самозакрывающийся, XMLReader запускает только ELEMENT, а не ELEMENT, а затем END_ELEMENT, как и ожидалось.
Обнаружение через свойство класса $ isEmptyElement также не работает, поскольку тег имеет атрибуты.
Поэтому мой вопрос: Как определить самозакрывающийся тег XML с помощью XMLReader в PHP?
Связано, но нет решения:
XmlReader — Самозакрывающийся элемент не запускает событие 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();
}
Других решений пока нет …