2016-09-30 95 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