使用PHP XMLReader检测XML自动关闭标签 [英] Detect XML self closing tags with PHP XMLReader

查看:101
本文介绍了使用PHP XMLReader检测XML自动关闭标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用XMLReader解析一个XML文档.我有一个带有所有常量的大小写开关.但是,如果某个标记是自动关闭的XMLReader,则只会触发ELEMENT,而不会触发ELEMENT,并且会像预期的那样触发END_ELEMENT.

I'd like to parse one XML document using XMLReader. I have a case switch with all the Constants. However, if a Tag is self-closing XMLReader only fires ELEMENT, not ELEMENT and than END_ELEMENT like expected.

通过类属性$ isEmptyElement进行检测也无法正常工作,因为标记具有属性.

Detection through class property $isEmptyElement does also not work because the tag has attributes.

因此,我的问题是:如何使用PHP中的XMLReader检测自动关闭的XML标签?

相关但没有解决方案: XmlReader-自关闭元素不会触发EndElement事件?

Related but no solution: 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;
    }
}

推荐答案

通过类属性$ isEmptyElement进行检测也无法正常工作,因为标记具有属性.

Detection through class property $isEmptyElement does also not work because the tag has attributes.

那是完全错误的.具有属性的空元素仍然为空,并且$isEmptyElement将反映出来.代码的问题是,移至属性后,您测试了$isEmptyElement.这会将当前节点更改为不是空元素的属性节点.像下面这样的东西应该起作用:

That's simply wrong. An empty element with attributes is still empty and $isEmptyElement will reflect that. The problem with your code is that you test $isEmptyElement after moving to the attributes. This will change the current node to an attribute node which isn't an empty element. Something like the following should work:

        $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();
        }

这篇关于使用PHP XMLReader检测XML自动关闭标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆