使用PHP XMLReader检测XML自我关闭标记

使用PHP XMLReader检测XML自我关闭标记

问题描述:

我想使用XMLReader解析一个XML文档。我有一个所有常量的情况开关。但是,如果标签是自闭的,则XMLReader仅触发ELEMENT,而不是像期望的那样触发ELEMENT和END_ELEMENT。使用PHP XMLReader检测XML自我关闭标记

通过类属性$ 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; 
    } 
} 

检测通过类属性$ 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(); 
     } 
+0

我会很高兴,如果是这样的话,可惜对我来说这将返回以下节点错误: 您是否在创建阅读器时设置了任何选项? 但是,$ hasValue是真实的,但这没有什么帮助,因为有很多没有价值的自闭标签。 – Marco

+0

我的意思是$ hasValue当然是错的。 – Marco

+0

那么我一定会犯一些其他的错误。我添加了我的代码,可以好好看看吗? – Marco