2015-05-03 43 views
2

我在黑客應該複製一個XML文件並編輯其中的一小部分它。現在編輯是好的,但有趣的是,複製可能相當複雜。這本質上是「逆向工程」工作,現在我知道我應該以某種方式保存某些元素的結束標記(即使元素 僅包含空白或爲空)。問題是,當HXT讀取 像複製保存某些元素的結束標記的XML文件

<tag> 
</tag> 

然後打印它作爲

<tag/> 

我可以告訴它始終使用顯式結束標記(或者無論你怎麼稱呼它) 指定爲withOutputXHTML選項writeDocument函數,但是 有元素寫成

<tag/> 

應該「照原樣」複製。

所以,基本上我的問題可以歸結爲:«如何複製這個文件保存的一些特定元素 結束標記?»:

參考/實驗
<foo> 
    <bar> 
    </bar> 
    <baz/> 
</foo> 

簡單複製程序:

module Main (main) where 

import Control.Monad (void) 
import Text.XML.HXT.Core 

main :: IO() 
main = void $ runX $ 
     readDocument [ withValidate no ] "test.xml" >>> 
     writeDocument [ withIndent yes 
        , withOutputEncoding isoLatin1 
        , withOutputXHTML ] "result.xml" 

回答

1

經過漫長的,令人沮喪的搜索,我決定嘗試 Text.XML.HXT.Arrow.XmlState中的每個選項。 有些選項只是沒有文檔字符串,所以這是一個猜謎遊戲。

最後,我發現這個奇蹟:

withNoEmptyElemFor :: [字符串] - > SYSCONFIG

雖然它沒有文檔字符串,它的名字聽起來比較看好的。事實上,通過此選項的幫助,我們可以指定「不能爲 空」的元素的名稱。

此選項可以與 writeDocumentconfigSysVars使用。 我更喜歡第二個箭頭,因爲我可以在本地使用它,這很有用,如果您有幾個箭頭執行稍微不同的 文檔,這些文檔可能有不同的標記集合,而這些標記集不應該是 爲空(這是我的情況)。

所以,回到我的例子中,我們可以通過編寫修復:

module Main (main) where 

import Control.Monad (void) 
import Text.XML.HXT.Core 

main :: IO() 
main = void $ runX $ 
     readDocument [ withValidate no ] "test.xml" >>> 
     writeDocument [ withIndent yes 
        , withOutputEncoding isoLatin1 
        , withNoEmptyElemFor ["bar"] ] "result.xml" 
0

在情況下,它是非常有用的,空白的保存爲XML的管道的默認行爲。以下內容不會摺疊您的<tag>元素,例如:

{-# LANGUAGE OverloadedStrings #-} 
import qualified Text.XML as X 

main :: IO() 
main = do 
    doc <- X.readFile X.def "foo.xml" 
    X.writeFile X.def "bar.xml" doc