2009-03-17 11 views
7

私はこのようなXML文書を持っている場合:HaskellではXML文書から文字列をどのように抽出しますか?

<root> 
    <elem name="Greeting"> 
    Hello 
    </elem> 
    <elem name="Name"> 
    Name 
    </elem> 
</root> 

と、このようないくつかのHaskellの種類/データの定義:

type Name = String 
type Value = String 
data LocalizedString = LS Name Value 

と、私は次のシグネチャでHaskellの関数を書きたかった:

getLocalizedStrings :: String -> [LocalizedString] 

最初のパラメータはXMLテキストで、戻り値は

[LS "Greeting" "Hello", LS "Name" "Name"] 

どうすればよいですか?

HaXmlが最適なツールである場合、上記の目標を達成するためにHaXmlをどのように使用しますか?

ありがとうございました!

答えて

5

HaXMLを使用してXML文書からビットを抽出する方法を実際には分かりませんでした。 HXTが私の必要をすべて満たしています。しかし、これはうまく動作します。あなたはおそらく、もう少しエラーチェックのような(実際<root>がルートであることを確認し<elem>等、直接の子孫である、すなわちちょうどいい加減に私のようatTagを使用していない)と思います

{-# LANGUAGE Arrows #-} 
import Data.Maybe 
import Text.XML.HXT.Arrow 

type Name = String 
type Value = String 
data LocalizedString = LS Name Value 

getLocalizedStrings :: String -> Maybe [LocalizedString] 
getLocalizedStrings = (.) listToMaybe . runLA $ xread >>> getRoot 

atTag :: ArrowXml a => String -> a XmlTree XmlTree 
atTag tag = deep $ isElem >>> hasName tag 

getRoot :: ArrowXml a => a XmlTree [LocalizedString] 
getRoot = atTag "root" >>> listA getElem 

getElem :: ArrowXml a => a XmlTree LocalizedString 
getElem = atTag "elem" >>> proc x -> do 
    name <- getAttrValue "name" -< x 
    value <- getChildren >>> getText -< x 
    returnA -< LS name value 

あなたの例では。今


あなたはArrow Sへの導入が必要な場合は、残念ながら私は、任意の良いものを知りません。私は自分自身でそれを "海に投げ入れて泳ぐ方法を学ぶ"ことを学びました。心に留めておくと便利かもしれ

何かがproc/-<構文はちょうどdo/<-のように、単に基本的な矢印操作(arr>>>、など)のための糖であることを基本的なモナド操作のための単純砂糖です(return,>>=など)。以下は等価です。

getAttrValue "name" &&& (getChildren >>> getText) >>^ uncurry LS 

proc x -> do 
    name <- getAttrValue "name" -< x 
    value <- getChildren >>> getText -< x 
    returnA -< LS name value 
+0

は非常に有益な答えをありがとうございましたしています! –

+0

http://www.haskell.org/haskellwiki/HXTにはHXTのチュートリアルがありますが、無意味な点はありません。したがって、これは矢印の表記法とどのように関連しているかを理解することは容易ではありません。 –

2

FWIW、HXTはシンプルTagSoupを行いますやり過ぎのように思える:)

1

ここでTagSoupと(他の人からいくつかの良い入力を受け取った後)私のの試みです:

最初の試みでは、文字列の空白を切り捨てるための単純な(そして誤りのある)方法が紹介されました。

+0

TagSoupは奇妙な入力をうまく受け入れます - あなたが実際に好きかもしれません:) - 残念ながらIMOはこの解決策を読むのが難しいです。マイナーニト:私は 'trimWhiteSpace = dropWhile isSpaceのようなものを期待していたでしょう。逆。 dropWhile isSpace。逆。あなたのものは 'removeAllWhiteSpace'のようなものです。 – ephemient

+0

ありがとうございました。私はいくつかのより良いサンプルデータを持っていたはずです。 :) XMLに改行がいくつか埋め込まれているので、isSpaceで改行が取り除かれていることを確認する必要があります。 –

+0

自分で試してみてください:GHCiに 'Data.Char.isSpace 'を入力してください。はい、改行は空白であり、常に空白です。私のニットはそれに関するものではなく、あなたの 'trimWhiteSpace" a b c "==" abc "'の行に沿っています。これは私にとって直感的ではありません。それとも、私は奇妙です。 – ephemient

3

XMLパッケージのいずれかを使用してください。

最も人気が、順番に、

  1. haxml
  2. HXT
  3. XML-光
  4. hexpat
関連する問題