2009-10-06 64 views
1

我有這樣從多條線路轉換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> 

一個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> 

你能推薦我怎麼能去這個,我想思維sed可能會幫助,但一直無法得到它的工作。

編輯:XML文件具有100K行類似種,編輯,以反映正確的輸入和輸出。

+0

文本編輯器+退格鍵? – 2009-10-06 04:00:44

+0

我有大約100K行,我將編輯該問題以反映 – kal 2009-10-06 04:20:49

回答

4

[XML ::嫩枝] [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+}{}' 

如果地址元素不正確的根目錄下,然後讓我們知道了,我會看看有什麼可以做的。

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> 

當然,「正確」的答案是使用一個解析器讀取該文件,然後去掉空格和縮進再次輸出。

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文件名(結果變量)。

+0

,您還可以在s.nextLine()之後添加trim()以刪除標籤之間的空白。 – 2009-10-06 05:32:05

2

你可以寫一個SAX解析器和每個事件只寫元素到另一個文件中沒有新的線路。這將刪除新行和垃圾空白。

-1

tr是一個非常簡單的方法來代替換行:

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

谷歌搜索「外殼更換新行」將產生很多其他的選擇了。

-1

正則表達式

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

除非隨後<address>將匹配標籤之間的CRLF +空間/標籤。雖然我通常會建議針對正則表達式和解析器,但在這種情況下,看起來這樣可以讓工作更輕鬆。

+0

請問downvoter請解釋投票嗎?該解決方案適用於示例數據,並且還存在關於正則表達式與解析器的警告。 – 2009-10-07 15:05:24

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從命令行運行樣式表。