使用 PHP XMLReader 检测 XML 自闭标签
Detect XML self closing tags with PHP XMLReader
我想使用 XMLReader 解析一份 XML 文档。我有一个带有所有常量的大小写开关。但是,如果标签是自关闭的 XMLReader 只会触发 ELEMENT,而不是 ELEMENT,并且会像预期的那样 END_ELEMENT。
通过class检测属性 $isEmptyElement 也不起作用,因为标签有属性。
因此我的问题是:如何在 PHP 中使用 XMLReader 检测自动关闭的 XML 标签?
相关但无解:
XmlReader - Self-closing element does not fire a EndElement event?
示例节点:
<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;
}
}
Detection through class property $isEmptyElement does also not work because the tag has attributes.
这是完全错误的。具有属性的空元素仍然是空的,$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();
}
我想使用 XMLReader 解析一份 XML 文档。我有一个带有所有常量的大小写开关。但是,如果标签是自关闭的 XMLReader 只会触发 ELEMENT,而不是 ELEMENT,并且会像预期的那样 END_ELEMENT。
通过class检测属性 $isEmptyElement 也不起作用,因为标签有属性。
因此我的问题是:如何在 PHP 中使用 XMLReader 检测自动关闭的 XML 标签?
相关但无解: XmlReader - Self-closing element does not fire a EndElement event?
示例节点:
<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;
}
}
Detection through class property $isEmptyElement does also not work because the tag has attributes.
这是完全错误的。具有属性的空元素仍然是空的,$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();
}