Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中更新DOM_Haskell - Fatal编程技术网

在Haskell中更新DOM

在Haskell中更新DOM,haskell,Haskell,我需要从文档中深度选择一个XML节点并对其进行转换,然后将其移动到另一个位置 此示例取自以下内容并稍作更改: 选择//d/e/f,然后更改f处的内容,并将新的f节点移动到a下 我需要多次执行此类操作,因此如果更新操作是可组合的,则效果更好 我正在查看xml导管包,但它似乎缺少DOM操作功能,执行此类任务的最佳方法是什么?我对HXT非常陌生,因此可能有更好的方法,但我解决了类似的问题,如: {-# OPTIONS_GHC -Wall #-} {-# LANGUAGE Arrows, NoMonom

我需要从文档中深度选择一个XML节点并对其进行转换,然后将其移动到另一个位置

此示例取自以下内容并稍作更改:

选择//d/e/f,然后更改f处的内容,并将新的f节点移动到a下

我需要多次执行此类操作,因此如果更新操作是可组合的,则效果更好


我正在查看xml导管包,但它似乎缺少DOM操作功能,执行此类任务的最佳方法是什么?

我对HXT非常陌生,因此可能有更好的方法,但我解决了类似的问题,如:

{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}

module Abc where

import Text.XML.HXT.Core

moveElts :: ArrowXml a => a XmlTree XmlTree
moveElts =
  processTopDown (
    -- Insert <f>'s under <a>:
    slurpF `when` hasName "a"
    >>>
    -- and remove the old <f>'s:
    removeChildrenExcept "f" `when` neg (hasName "a")
    )
  where
    removeChildrenExcept tag =
      replaceChildren (getChildren >>> neg (hasName tag))
    slurpF = proc a -> do
      elts <- deep (hasName "f") -< a
      returnA (insertChildrenAt 0 (constA elts)) -<< a


-- Test:
test :: IO ()
test = runX (readDocument [withValidate no] "abc.xml"
             >>> moveElts
             >>> writeDocumentToString [withIndent yes])
       >>= putStrLn . head

你所说的DOM操纵是什么意思?与Haskell中的大多数数据结构一样,xml管道使用的数据结构是不可变的。转换XML树的方法是创建一个新的树。如果你能更详细地描述你想要实现的目标,你可能会得到更多的信息。@MichaelSnoyman谢谢Michael,我已经更新了问题,并且阅读了你的问题解决方案,但是我不想将选择逻辑硬编码成递归,如果xml导管有更新或插入功能就好了。@MichaelSnoyman同样,似乎xml导管是使用Zipper实现的,选择f cur$//element d$/element e$/element f很容易,但是如果我做了一些更改并想返回到原始树中进行更改,我该怎么办?拉链孔和拉链上下文构成了整棵树,它应该有返回的方式,对吗?我曾经在反XML中使用过这个,请看这里:从“现在开始”一段中的棘手部分开始。XML管道API并不鼓励这种用法。然而,它看起来正是镜头包装所支持的那种用法。我自己没有用过,但我建议看一看。@MichaelSnoyman xml lens似乎是一个基于镜头的xml选择器,不进行转换,xml管道轴也可以进行选择工作。我觉得xml管道只有zippers导航功能,加上一些过滤器,但没有合并上下文和聚焦回原始树功能,这些功能也很有用。
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}

module Abc where

import Text.XML.HXT.Core

moveElts :: ArrowXml a => a XmlTree XmlTree
moveElts =
  processTopDown (
    -- Insert <f>'s under <a>:
    slurpF `when` hasName "a"
    >>>
    -- and remove the old <f>'s:
    removeChildrenExcept "f" `when` neg (hasName "a")
    )
  where
    removeChildrenExcept tag =
      replaceChildren (getChildren >>> neg (hasName tag))
    slurpF = proc a -> do
      elts <- deep (hasName "f") -< a
      returnA (insertChildrenAt 0 (constA elts)) -<< a


-- Test:
test :: IO ()
test = runX (readDocument [withValidate no] "abc.xml"
             >>> moveElts
             >>> writeDocumentToString [withIndent yes])
       >>= putStrLn . head