将XML输入从多行转换为一行

时间:2009-10-06 03:57:02

标签: java xml perl sed

我有像这样的xml

<address>
   <street>abc</street>
   <number>123</number>
</address>

<address>
   <street>abc1</street>
   <number>345</number>
</address>

...
...
<address>
   <street>xyz</street>
   <number>999</number>
</address>

我希望能够将其转换为

<address><street>abc</street><number>123</number></address>
<address><street>abc1</street><number>345</number></address>
...
...
<address><street>xyz</street><number>999</number></address>

你能推荐我怎样才能解决这个问题,我觉得sed可能有所帮助,但却无法让它发挥作用。

编辑:XML文件有100K类似的类,经过编辑以反映正确的输入和输出。

9 个答案:

答案 0 :(得分:4)

[XML :: Twig] [1]附带一个xml漂亮的打印机xml_pp。如果地址行位于文档的根目录下,那么您可以使用它来实际接近所需的输出:

xml_pp -s record_c to_compact.xml

<root>
  <address><street>abc</street><number>123</number></address>
  <address><street>abc1</street><number>345</number></address>
  <address><street>xyz</street><number>999</number></address>
  <address><street>abc</street><number>123</number></address>
  <address><street>abc1</street><number>345</number></address>
  <address><street>xyz</street><number>999</number></address>
</root>

删除地址行开头的空格非常简单:

xml_pp -s record_c to_compact.xml | perl -p -e's{^\s+}{}'

如果地址元素不在根目录下,请告诉我们,我会看到可以做些什么。

答案 1 :(得分:3)

我不确定它的命令行语法,但是这个正则表达式应该这样做:

// Find:
/>[\n\s]+</
// Replace with:
><

这只会删除元素之间的空白区域(不在它们内部,除非它可能是CDATA部分),但是你可能会意外删除一些你真正想要的空格,例如:

<p>here's <i>something</i> <b>interesting</b></p>
// becomes:
<p>here's <i>something</i><b>interesting</b></p>

以下是我提到的CDATA问题的一个例子:

<element><![CDATA[
    this shouldn't <blah>
    <blah> be touched.
]]></element>

// becomes:
<element><![CDATA[
    this shouldn't <blah><blah> be touched.
]]></element>

当然,“正确”的答案是使用解析器来读取文件,然后在删除空格和缩进的情况下再次输出它。

答案 2 :(得分:3)

另一种选择是使用XSLT样式表来复制所有内容,但只复制地址元素中的元素和属性:

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

    <xsl:template match="address">
        <xsl:copy>
            <xsl:apply-templates select="@*|*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

与正则表达式方法不同,这适用于任何XML文档(即使换行符被编码为字符实体或CDATA),并且只会格式化地址元素。

您可以使用Java运行样式表,也可以使用xsltproc从命令行运行样式表。

答案 3 :(得分:2)

您可以编写SAX解析器,并且在每个事件上只需将元素写入另一个文件而无需新行。这将删除新行和垃圾空白。

答案 4 :(得分:1)

您可以尝试使用此代码(Java):

import java.util.Scanner;
import java.io.File;
import java.io.FileWriter;
public class TrimLines {
  public static void main(String[] args){
    try {
        String source = "employee.xml";
        String result = "no-lines-employee.xml";

        System.out.println("removing lines...");
        Scanner s = new Scanner(new File(source));          
        FileWriter w = new FileWriter(result);          
        while(s.hasNext())              
            w.write(s.nextLine());          
        w.close();          
        System.out.println("remove successfull.");
    }
    catch(Exception ex){
        ex.printStackTrace();
    }
  } 
}

只需指定源xml文件名(源变量)和目标xml文件名(结果变量)。

答案 5 :(得分:0)

尝试此选项: 在记事本++>打开xml文件>选择所有内容中,然后在编辑中选择>空白操作> 删除不必要的空格和EOL。

这对我有用。

答案 6 :(得分:-1)

这个链接可以帮到你。他们的例子有点复杂,但不应该很难改变以满足您的需求: http://www.unix.com/unix-dummies-questions-answers/40871-remove-carriage-return-between-line.html

-don

答案 7 :(得分:-1)

tr是替换换行符的一种非常简单的方法:

cat addresses.xml | tr -d '\n'

谷歌搜索“shell替换换行符”也将产生许多其他选项。

答案 8 :(得分:-1)

正则表达式

(?<=>)\r?\n[ \t]*(?!<address)

将匹配标记之间的CRLF +空格/标记,除非后跟<address>。虽然我通常建议不要使用正则表达式和解析器,但在这种情况下,看起来这样可以轻松完成工作。