Java:将格式化的xml文件转换为一行字符串

Posted

技术标签:

【中文标题】Java:将格式化的xml文件转换为一行字符串【英文标题】:Java : Convert formatted xml file to one line string 【发布时间】:2011-07-27 12:49:57 【问题描述】:

我有一个格式化的 XML 文件,我想将它转换为一个行字符串,我该怎么做。

示例 xml:

<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book>
       <title>Basic XML</title>
       <price>100</price>
       <qty>5</qty>
   </book>
   <book>
     <title>Basic Java</title>
     <price>200</price>
     <qty>15</qty>
   </book>
</books>

预期输出

<?xml version="1.0" encoding="UTF-8"?><books><book> <title>Basic XML</title><price>100</price><qty>5</qty></book><book><title>Basic Java</title><price>200</price><qty>15</qty></book></books>

提前致谢。

【问题讨论】:

这应该没有必要。为什么需要它? @Tomalak 我需要将它作为输入传递给 cgi,并且 cgi 只接受单行形式的 xml。 @All,非常感谢所有的答案 【参考方案1】:

Underscore-java 库有静态方法 U.formatXml(xmlstring)。 Live example

import com.github.underscore.U;
import com.github.underscore.Xml;

public class MyClass 
    public static void main(String[] args) 
        System.out.println(U.formatXml("<a>\n  <b></b>\n  <b></b>\n</a>",
        Xml.XmlStringBuilder.Step.COMPACT));
    


// output: <a><b></b><b></b></a>

【讨论】:

【参考方案2】:

通过带有&lt;xsl:output indent="no"&gt;&lt;xsl:strip-space elements="*"/&gt; 的XSLT identity transform 运行它

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="no" />
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

它将删除任何不重要的空白并产生您发布的预期输出。

【讨论】:

这似乎是一个不错的方法,但您没有提到如何在 Java 中运行这个 XSLT? XSLT processing with Java【参考方案3】:

Java 1.8 及以上版本

BufferedReader br = new BufferedReader(new FileReader(filePath));
String content = br.lines().collect(Collectors.joining("\n"));

【讨论】:

如果 OP 想要缩小 XML,这样的方法可能适用于大多数文档:reader.lines().map(String::trim).collect(Collectors.joining());。注意:如果元素属性被拆分为多行,它可能会失败。【参考方案4】:

如果您要压缩 XML 文档中的所有空白,则上述解决方案有效。输出 XML 文档时,其他快速选项是 JDOM(使用 Format.getCompactFormat())和 dom4j(使用 OutputFormat.createCompactFormat())。

但是,我有一个独特的要求,即保留元素文本值中包含的空白,而这些解决方案并没有按我的需要工作。我只需要删除添加到 XML 文档中的“漂亮打印”格式。

我想出的解决方案可以在下面的 3 步/正则表达式过程中解释......为了理解解决方案的算法。

String regex, updatedXml;

// 1. remove all white space preceding a begin element tag:
regex = "[\\n\\s]+(\\<[^/])";
updatedXml = originalXmlStr.replaceAll( regex, "$1" );

// 2. remove all white space following an end element tag:
regex = "(\\</[a-zA-Z0-9-_\\.:]+\\>)[\\s]+";
updatedXml = updatedXml.replaceAll( regex, "$1" );

// 3. remove all white space following an empty element tag
// (<some-element xmlns:attr1="some-value".... />):
regex = "(/\\>)[\\s]+";
updatedXml = updatedXml.replaceAll( regex, "$1" );

注意:伪代码在 Java 中......“$1”是替换字符串,它是第一个捕获组。

这将简单地删除在将“漂亮打印”格式添加到 XML 文档时使用的空白,但当它是元素文本值的一部分时保留所有其他空白。

【讨论】:

【参考方案5】:
// 1. Read xml from file to StringBuilder (StringBuffer)
// 2. call s = stringBuffer.toString()
// 3. remove all "\n" and "\t": 
s.replaceAll("\n",""); 
s.replaceAll("\t","");

编辑:

我犯了一个小错误,在你的情况下最好使用StringBuilder(我想你不需要线程安全的StringBuffer)

【讨论】:

如果内容元素之间有空格怎么办? foo (newline) bar? 双空格,看看预期的结果,我们有例如 - 书之后是空格。我不认为@sprena 想用空格做点什么。 示例中似乎有错误,b/c 其他 组合之间没有空格 这是一个错字,中间不能有空格。对此感到抱歉。【参考方案6】:
FileUtils.readFileToString(fileName);

link

【讨论】:

该链接甚至表明该方法已折旧。如果使用 trim 读取简单的缓冲区就足够了,我不建议使用此方法【参考方案7】:

打开并读取文件。

Reader r = new BufferedReader(filename);
String ret = "";
while((String s = r.nextLine()!=null)) 

  ret+=s;

return ret;

【讨论】:

ret +=s :(( 不要那样做,最好使用 StringBuffer @smas :P 这不是真正的代码,我还没有想出在这个网站上正确格式化,所以我选择了最简洁的方式。思路依旧(如果导入相关库,设置filename之类的变量,设置trytry catch块) 不要像 smas 建议的那样使用字符串 concat 或 stringbuffer,使用 StringBuilder kaioa.com/node/59【参考方案8】:

Using this answer which provides the code to use Dom4j to do pretty-printing,将设置输出格式的行从:createPrettyPrint()更改为:createCompactFormat()

public String unPrettyPrint(final String xml)  

    if (StringUtils.isBlank(xml)) 
        throw new RuntimeException("xml was null or blank in unPrettyPrint()");
    

    final StringWriter sw;

    try 
        final OutputFormat format = OutputFormat.createCompactFormat();
        final org.dom4j.Document document = DocumentHelper.parseText(xml);
        sw = new StringWriter();
        final XMLWriter writer = new XMLWriter(sw, format);
        writer.write(document);
    
    catch (Exception e) 
        throw new RuntimeException("Error un-pretty printing xml:\n" + xml, e);
    
    return sw.toString();

【讨论】:

非常适合我。谢谢【参考方案9】:
//filename is filepath string
BufferedReader br = new BufferedReader(new FileReader(new File(filename)));
String line;
StringBuilder sb = new StringBuilder();

while((line=br.readLine())!= null)
    sb.append(line.trim());

使用 StringBuilder 比 concat http://kaioa.com/node/59 更有效

【讨论】:

这不会删除前导/尾随空格,不是吗? 这不尊重 XML 文档中提到的编码,是吗? 对于偏离主题的评论感到抱歉,但该链接已过期并将用户重定向到不相关的域。【参考方案10】:

我猜你想读入,忽略空白,然后再写出来。大多数 XML 包都有忽略空格的选项。例如,DocumentBuilderFactory 有 setIgnoringElementContentWhitespace 用于此目的。

同样,如果您通过编组对象生成 XML,那么 JAXB 具有 JAXB_FORMATTED_OUTPUT

【讨论】:

以上是关于Java:将格式化的xml文件转换为一行字符串的主要内容,如果未能解决你的问题,请参考以下文章

将 CSV 转换为 XML 文件的 Java lib 或应用程序? [关闭]

C#里如何将XML格式字符串转成XML文件?

将 Java 日期转换为 XML 日期格式(反之亦然)

我们有任何工具可以将 Android xml 布局转换为 .java 文件吗?

将 Java 对象转换为 XML 字符串

Java处理xml格式的文件或字符串使用哪些技术