2013-10-27 111 views
1

我有一個XML格式是這樣的:對保留空白/縮進的XML進行排序?

<?xml version="1.0" encoding="Windows-1252"?> 
<!--MasterMusik Video Database--> 
<Videos> 
    <Video><Name>SKRILLEX &amp; WOLFGANG GARTNER - THE DEVIL's DEN</Name><Genre>Techno</Genre><Format>mp4</Format><HD>HD</HD><Resolution>1280x720</Resolution><Size>70,57</Size></Video> 
    <Video><Name>4 Strings - Let It Rain</Name><Genre>Dance</Genre><Format>mp4</Format><HD>HD</HD><Resolution>1920x1080</Resolution><Size>129,3</Size></Video> 
    <Video><Name>Deadmau5 - I Remember (Live At Roskilde Festival)</Name><Genre>Trance</Genre><Format>mkv</Format><HD>SD</HD><Resolution>704x384</Resolution><Size>97,99</Size></Video> 
</Videos> 

我想通過自己的「名稱」標籤中的元素進行排序。

這是我使用的元素Sort XML document

Private Function XML_Sort(ByVal xdoc As XDocument, _ 
          ByVal Root_Element As String, _ 
          ByVal Element_to_sort As String) As XDocument 

    Try 

     xdoc.Root.ReplaceNodes(xdoc.Root.Elements(Root_Element) _ 
           .OrderBy(Function(sort) sort.Element(Element_to_sort).Value)) 

     Return xdoc 

    Catch ex As Exception 
     Throw New Exception(ex.Message) 

    End Try 

End Function 

但我得到的輸出排序的功能是完全縮進:

<!--MasterMusik Video Database--> 
<Videos> 
    <Video> 
    <Name>4 Strings - Let It Rain</Name> 
    <Genre>Dance</Genre> 
    <Format>mp4</Format> 
    <HD>HD</HD> 
    <Resolution>1920x1080</Resolution> 
    <Size>129,3</Size> 
    </Video> 
    <Video> 
    <Name>Deadmau5 - I Remember (Live At Roskilde Festival)</Name> 
    <Genre>Trance</Genre> 
    <Format>mkv</Format> 
    <HD>SD</HD> 
    <Resolution>704x384</Resolution> 
    <Size>97,99</Size> 
    </Video> 
    <Video> 
    <Name>SKRILLEX &amp; WOLFGANG GARTNER - THE DEVIL's DEN</Name> 
    <Genre>Techno</Genre> 
    <Format>mp4</Format> 
    <HD>HD</HD> 
    <Resolution>1280x720</Resolution> 
    <Size>70,57</Size> 
    </Video> 
</Videos> 

這是我使用的用法:

Dim xdoc As XDocument = _ 
    XDocument.Load("Videos.xml", LoadOptions.PreserveWhitespace) 

xdoc = XML_Sort(xdoc, "Video", "Name") 

IO.File.WriteAllText("Sorted Videox.xml", xdoc.ToString) 

此時有兩個問題:

  1. 輸出是縮進的。

  2. XML的聲明沒有寫入<?xml version="1.0" encoding="Windows-1252"?>,我需要手動編寫它。

我該如何解決這兩個問題?

+1

爲了節省您可以簡單地使用['XDocument.Save']的XML(http://msdn.microsoft.com/en-us /library/bb551426.aspx)。這將寫入包含頭部的有效XML('ToString'去除頭部)。 – pescolino

+0

我很想知道爲什麼你需要這種格式的XML。這聽起來像是耗費代碼的問題。 –

+0

@Ian Nelson這是一個文件大小的問題,格式化代碼的文件大小是12 MB而不是20 MB使用「正常」格式,它沒有太大的區別(目前),但最重要的是我如果每個文件/屬性分組在一行中,就可以更好地讀取/找到每個寫在XML內的文件的信息,就像您可以在此問題頂部的XML格式示例中看到的一樣,但在嘗試對丟失的XML元素進行排序後格式化。 PS:對不起,我的英語。 – ElektroStudios

回答

2

一旦你開始你的操作XDocument,格式丟失。你的排序方法只返回一個純XML元素列表。因此,您有兩種選擇:

  1. 使用文本比較對文件進行排序。這不應該太難,因爲<Name>是在該行的第一個標籤,所以只需將文本行按字母順序排序應該足夠了:

    Dim lines = File.ReadAllLines("Videos.xml") 
    Dim toSort = lines.Skip(3).Take(lines.Length - 4) ' skip first three and last line ' 
    Dim result = 
        lines.Take(3).Concat(toSort.OrderBy(Function(s) s)).Concat({lines.Last}) 
    File.WriteAllLines("Sorted.xml", result.ToArray()) 
    
  2. 另外,做您排序(或者任何你想做)使用的XDocument,但使用自己的輸出程序:

    Dim sb As New StringBuilder() 
    sb.AppendLine("<?xml version=""1.0"" encoding=""Windows-1252""?>") 
    sb.AppendLine("<!--MasterMusic Video Database-->") 
    sb.AppendLine("<Videos>") 
    For Each video In xdoc.Root.Elements 
        sb.AppendLine(" " & video.ToString(SaveOptions.DisableFormatting)) 
    Next 
    sb.AppendLine("</Videos>") 
    File.WriteAllText("Sorted.xml", sb.ToString(), Encoding.GetEncoding(1252)) 
    
+0

謝謝,現在解決了,我會接受這個答案,直到23小時,賞金說我不能。 – ElektroStudios

+0

你能解決最後一行參數嗎?第一個參數是一個文件路徑,第二個參數是sb,最後一個是編碼,但是新編碼(1252)參數表示新的不能使用。那麼如何將該文件保存爲ANSI編碼? – ElektroStudios

+1

@ElektroStudios:謝謝,修正。正確的語法是調用'Encoding.GetEncoding'。 'Encoding(int)'構造函數受到保護。 – Heinzi

2

試試這個

IO.File.WriteAllText("Sorted Videox.xml", xdoc.ToString(SaveOptions.DisableFormatting)) 
+0

Thankyou但不工作,我得到一個「AllInOne線」沒有任何格式。 – pitoloko