PHP-删除XML空节点

时间:2018-07-03 18:42:48

标签: php xml

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

public static void main(String[] args){

    Scanner scan = new Scanner(System.in);

    int[][] itemsCart;
    int itemsInTheCart=0;
    int itemsPrice = 0;
    System.out.print("Please enter the number of items in your cart: ");
    itemsInTheCart = scan.nextInt();
    itemsCart= new int[itemsInTheCart][2];
    for(int i = 0; i < itemsInTheCart; i++){
        System.out.print("Enter the price for item " + (i+1) + ": ");

        itemsPrice = scan.nextInt();

        itemsCart[i][1] = itemsPrice;
    }
    // for testing
    for (int i=0;i<itemsInTheCart;i++){
        System.out.println("Item: "+(i+1)+" for price: "+ itemsCart[i][1] );
    }
}

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

2 个答案:

答案 0 :(得分:1)

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

这里是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>

答案 1 :(得分:0)

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

使用顶级PHP和XSLT StackOverflow用户查看XSLT Fiddle Demo,其中每个 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);