2016-09-30 96 views
0

我有一個xml字符串,我想從中刪除空元素和包含該元素的行。刪除空元素xml string java?

所以FIR例如:

XML:

<ct> 
    <c>http://192.168.105.213</c> 
    <l>http://192.168.105.213</l> 
    <o></o> 
    <l>http://192.168.105.213</l> 
    <o>http://192.168.105.213</o> 
<ct> 

在這種<o></o>是空的元素,所以刪除此元素後,我想:

<ct> 
     <c>http://192.168.105.213</c> 
     <l>http://192.168.105.213</l> 
     <l>http://192.168.105.213</l> 
     <o>http://192.168.105.213</o> 
    <ct> 

所以整條生產線必須是刪除,使其後退。

我想:xml.replaceAll("<(\\w+)></\\1>", ""));

這使得兩者之間的空行:

<ct> 
    <c>http://192.168.105.213</c> 
    <l>http://192.168.105.213</l> 

    <l>http://192.168.105.213</l> 
    <o>http://192.168.105.213</o> 
</ct> 

如何刪除空間或\n, \t, \r正確地得到正確的縮進?

+2

請,做不使用正則表達式來解析XML。決不。見http://stackoverflow.com/questions/6751105/why-its-not-possible-to-use-regex-to-parse-html-xml-a-formal-explanation-in-la – vanje

+2

@vanje我喜歡這個更好地回答:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags –

+0

@托馬斯:是的,你說得對。 – vanje

回答

2

這會工作:

xml.replaceAll("<(\\w+)></\\1>\n\\s+", "")); 

這將匹配一個新行後跟一個或多個空的空間(包括標籤),這是由你的模式之前。

編輯:xml.replaceAll("\n\\s+<(\\w+)></\\1>", "")也應該更深層次的工作。

如果你希望根元素也爲空和任何一個子元素來會出現意想不到的,則可能需要進行換行和空格可選的,因爲

xml.replaceAll("\n?\\s*<(\\w+)></\\1>", "") 
+0

它適用於一級縮進,但是對於深度嵌套的空元素,這是否會移除適當的空格以維持縮進? –

+0

@SiddharthTrikha請在編輯標籤前加上換行符+空格組合。它應該適用於更深的。 –

1

這應該解決它爲你

xml.replaceAll("\n\t<(\\w+)></\\1>", ""); 
1

正如評論中的建議,重新考慮在HTML/XML文檔中直接使用正則表達式,因爲這些不是常規語言。相反,在解析的文本/值內容上使用正則表達式,但不能轉換文檔。

一個偉大的XML操縱工具是XSLT,轉換語言和兄弟到XPath。 Java帶有內置的XSLT 1.0處理器,並且還可以調用或獲取外部處理器(Xalan, Saxon, etc.)。考慮以下設置:

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 Such Nodes --> 
    <xsl:template match="*[.='']"/> 

</xsl:transform> 

的Java代碼

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 

import javax.xml.transform.*; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.transform.OutputKeys; 

import java.io.File; 
import java.io.IOException; 
import java.net.URISyntaxException; 

import org.w3c.dom.Document; 
import org.xml.sax.SAXException; 

public class XMLTransform { 
    public static void main(String[] args) throws IOException, URISyntaxException, 
                SAXException, ParserConfigurationException, 
                TransformerException {    
      // Load XML and XSL Document 
      String inputXML = "path/to/Input.xml"; 
      String xslFile = "path/to/XSLT/Script.xsl"; 
      String outputXML = "path/to/Output.xml"; 

      Source xslt = new StreamSource(new File(xslFile));    
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();    
      DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 
      Document doc = docBuilder.parse (new File(inputXML)); 

      // XSLT Transformation with pretty print 
      TransformerFactory prettyPrint = TransformerFactory.newInstance(); 
      Transformer transformer = prettyPrint.newTransformer(xslt); 

      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
      transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); 
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); 
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
      transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
      transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");       

      DOMSource source = new DOMSource(doc); 
      StreamResult result = new StreamResult(new File(outputXML));   
      transformer.transform(source, result); 
    } 
} 

輸出

<ct> 
    <c>http://192.168.105.213</c> 
    <l>http://192.168.105.213</l> 
    <l>http://192.168.105.213</l> 
    <o>http://192.168.105.213</o> 
</ct> 

NAMESPACES

當使用命名空間的,如下面的XML:

<prefix:ct xmlns:prefix="http://www.example.com"> 
    <c>http://192.168.105.213</c> 
    <l>http://192.168.105.213</l> 
    <o></o> 
    <l>http://192.168.105.213</l> 
    <o>http://192.168.105.213</o> 
</prefix:ct> 

使用下面的XSLT與聲明中的頭,並添加模板:

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

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

    <!-- Retain Namespace Prefix --> 
    <xsl:template match="ct"> 
    <xsl:element name='prefix:{local-name()}' namespace='http://www.example.com'> 
     <xsl:copy-of select="namespace::*"/> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
    </xsl:template> 

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

</xsl:transform> 

輸出

<prefix:ct xmlns:prefix="http://www.example.com"> 
    <c>http://192.168.105.213</c> 
    <l>http://192.168.105.213</l> 
    <l>http://192.168.105.213</l> 
    <o>http://192.168.105.213</o> 
</prefix:ct> 
+0

我最初嘗試使用與您給出的模板相同的XSLT,但沒有這個部分'<! - 空模板移除此類節點 - > ',那裏有空的空間。隨着這最後一部分的添加,將嘗試這一點。這會刪除空格嗎? –

+0

基本上,壓痕的空白區域也被剝離了。 –

+0

是的,如圖所示。事實上,那個模板匹配是腳本的關鍵項目。身份轉換將原樣複製整個文檔,因此如果您將此空白模板取消,則不會進行任何更改。同樣使用''刪除不需要的空格。 – Parfait