2

我正在破解一个应该复制 XML 文件并编辑它的一小部分的东西。现在编辑没问题,但有趣的是,复制可能相当棘手。这本质上是“逆向工程”工作,现在我知道我应该以某种方式保留某些元素的结束标签(即使元素仅包含空格或为空)。问题是当 HXT 读取类似

<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"
4

2 回答 2

1

经过漫长而令人沮丧的搜索,我决定尝试 Text.XML.HXT.Arrow.XmlState中的每个选项。有些选项没有文档字符串,所以这是一个猜谜游戏。

最后,我发现了这个奇迹:

withNoEmptyElemFor :: [String] -> SysConfig

虽然它没有文档字符串,但它的名字听起来很有前途。实际上,借助此选项,我们可以指定“不能为空”的元素名称。

此选项可与 writeDocument 或 一起使用configSysVars。我更喜欢第二个箭头,因为我可以在本地使用它,如果您有多个箭头来执行稍微不同的文档的处理,这些文档可能具有不同的标签集合,这些标签不应该为空(这是我的情况)。

所以,回到我的例子,我们可以通过编写来修复它:

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"
于 2015-05-03T12:00:56.997 回答
0

如果有用,空白保留是 xml-conduit 的默认行为。以下内容不会折叠您的<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
于 2015-05-03T13:19:03.167 回答