繁体   English   中英

PHP-删除XML空节点

[英]PHP - removing XML empty nodes

我发现这段代码可以删除XML文件中的空节点,但无法正常工作。 留下一个确实需要删除的空节点。 是的,它是空的,只有空白。

$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
$domxml->loadXML($this->response);
$this->response = $domxml->saveXML($domxml->documentElement);

有人知道有更好的方法吗?

换句话说,您要删除任何没有文本内容,没有属性,没有具有文本内容或属性的子元素并且具有父元素节点(不是文档元素)的元素节点。

这是一个Xpath函数normalize-space() ,它将所有空格序列转换为单个空格,并从开始/结尾剥离它们。 任何仅包含空格的内容都将导致一个空字符串。

Xpath的

//*获取列表中文档中的任何元素节点。 您只需要添加条件。

  • 没有文字内容
    normalize-space(.) = ""
  • 没有属性
    not(@*)
  • 没有包含内容的后代节点(包括注释,...)
    not(.//node()[normalize-space(.) != ""])
  • 没有具有属性的后代元素节点
    not(.//*[@*])
  • 有一个父元素节点
    parent::*

放在一起:

$xml = <<<'XML'
<foo>
  <bar></bar>
  <bar>123</bar>
  <bar foo="123"></bar>
  <bar><foo>   </foo></bar>
  <bar><!-- test --></bar>
</foo>
XML;

$document = new DOMDocument();
$document->preserveWhiteSpace = FALSE;
$document->formatOutput = TRUE; 
$document->loadXml($xml);
$xpath = new DOMXpath($document);

$expression = 
  '//*[
    normalize-space(.) = "" and 
    not(@*) and  
    not(.//node()[normalize-space(.) != ""]) and 
    not(.//*[@*]) and
    parent::*
  ]';

$nodes = $xpath->evaluate($expression);
for ($i = $nodes->length - 1; $i >= 0; $i--) {
  $nodes[$i]->parentNode->removeChild($nodes[$i]);
}

echo $document->saveXml();

输出:

<?xml version="1.0"?>
<foo>
  <bar>123</bar>
  <bar foo="123"/>
  <bar>
    <!-- test -->
  </bar>
</foo>

对于通用解决方案,例如所有空节点,请考虑使用XSLT。 具体来说,请使用一个空模板(转换为副本或不设置样式),该模板与文档中带有*且文本值等于空[.='']条件的所有节点匹配。

请参阅使用PHP和XSLT StackOverflow顶级用户的XSLT Fiddle演示 ,其中每个topusers节点至少有一个空子级,在结果中将其完全删除。

XSLT (另存为.xsl)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <!-- Identity Transform to Copy Document as is -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Empty Template to Remove Empty Nodes -->
  <xsl:template match="*[.='']"/>

</xsl:transform>

PHP (如果需要,请在.ini文件中启用php_xsl扩展名)

// LOAD XML
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load('Input.xml');

// LOAD XSLT 
$xsl = new DOMDocument('1.0', 'UTF-8');   
$xsl->load('XSLT_Script.xsl');

// INITIALIZE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// RUN TRANSFORMATION
$newXML = $proc->transformToXML($xml);

// SAVE NEW TREE TO FILE
echo $newXML;
file_put_contents('Output.xml', $newXML);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM