Как получить доступ к некоторым данным XML с помощью Haskell (используя HaXml)? - PullRequest
7 голосов
/ 21 мая 2011

Я хочу получить доступ к данным XML-файла, например

<?xml version="1.0"?>
<MY>
  <Foo id="1" name="test">
    <Argument name="a" />
  </Foo>
  <Foo id="2" name="test2">
    <Argument name="a" />
    <Argument name="b" />
  </Foo>
  <Other id="2" name="someOther"/>
</MY>

Я хочу, например, чтобы прочитать каждый Foo с его аргументами, как я могу сделать это с Haskell? (Я хотел бы использовать модуль HaXml)

Я не знаю с чего начать.

Ответы [ 5 ]

5 голосов
/ 28 августа 2011

Да, документация является большим минусом в отношении haskell.Интересно, почему люди из Haskell так ненавидят документирование своего кода.Нет необходимости в жирной бумаге, несколько примеров использования обычно более чем достаточно.

Также здесь можно найти небольшой пример использования HaXML: http://book.realworldhaskell.org/read/extended-example-web-client-programming.html

5 голосов
/ 21 мая 2011

Для простых задач вы можете рассмотреть пакет tagoup.

3 голосов
/ 23 мая 2011

Не могу найти актуальную документацию и примеры для haXml.

Однако имеется некоторая документация для HXT. Я знаю, что это, вероятно, излишество для вашего примера, но в любом случае.

Если вы хотите использовать tagoup, возможно, вам помогут следующие ответы:
парсер xml-дерева (Haskell) для библиотеки графов
Как в Haskell вы извлекаете строки из XML-документа?

Вот документация с примерами для HXT:
http://www.haskell.org/haskellwiki/HXT/Conversion_of_Haskell_data_from/to_XML
http://www.haskell.org/haskellwiki/HXT
http://www.haskell.org/haskellwiki/HXT/Practical
http://en.wikibooks.org/wiki/Haskell/XML

Теперь код с использованием HXT. (предупреждение, я не уверен, что это правильный путь)

Я следовал уроку: http://www.haskell.org/haskellwiki/HXT/Conversion_of_Haskell_data_from/to_XML

вам нужен ваш xml файл как "data.xml"

import Data.Map (Map, fromList, toList)
import Text.XML.HXT.Core


type Foos = Map String [Foo]

data Foo = Foo
     { 
       fooId :: String 
     , fooName :: String
     , arguments :: [Argument]  
     } 
          deriving (Show, Eq)



data Argument = Argument
      { argName  :: String
      }
           deriving (Show, Eq)

instance XmlPickler Foo where
  xpickle = xpFoo


instance XmlPickler Argument where
  xpickle = xpArgument

-- WHY do we need this?? no clue            
instance XmlPickler Char where
    xpickle = xpPrim

-- this could be wrong
xpFoos :: PU Foos
xpFoos
  = xpWrap (fromList
          , toList
          ) $
  xpList $
      xpElem "MY" $ 
      xpickle

xpFoo :: PU Foo
xpFoo
  = xpElem "Foo" $
     xpWrap ( uncurry3 Foo
            , \ f -> (fooId f
                      , fooName f
                      , arguments f
                     )  
           ) $          
    xpTriple (xpAttr "id" xpText) 
              (xpAttr "name" xpText)
              (xpList xpickle)


xpArgument :: PU Argument
xpArgument
    = xpElem "Argument" $
       xpWrap ( \ ((a)) -> Argument a
               , \ t -> (argName t)
              ) $
       (xpAttr "name" xpText )


main    :: IO ()
main
     = do
       runX ( xunpickleDocument xpFoos
                                [ withValidate no
                                , withTrace 1
                                , withRemoveWS yes
                                , withPreserveComment no
                                ] "data.xml"
         >>>
             arrIO ( \ x -> do {print x ; return x}) 
            )
       return ()

РЕЗУЛЬТАТ (вам нужен пример xml как "data.xml"):

-- (1) getXmlContents
-- (1) readDocument: "data.xml" (mime type: "text/xml" ) will be processed
-- (1) readDocument: "data.xml" processed
fromList [("",[Foo {fooId = "1", fooName = "test", arguments = [Argument {argName = "a"}]},
Foo {fooId = "2", fooName = "test2", arguments = [Argument {argName = "a"},
Argument     {argName = "b"}]}])]
1 голос
/ 26 марта 2012

С xml -роводником вы можете сделать это очень просто и просто:

{-# LANGUAGE OverloadedStrings #-}

import Data.Conduit
import qualified Text.XML.Stream.Parse as XP
import Data.String(fromString)

parseFile fileName = runResourceT $ XP.parseFile XP.def (fromString fn) 
                                  $$ parseXML

parseXML = XP.force $ XP.tagNoAttr "MY"
         $ XP.many 
         $ XP.tagName "foo" (mapM XP.requiredAttr ["id", "name"]) 
                            $ \(~[i,n]) -> return (i,n)
0 голосов
/ 07 августа 2015

Существует учебное пособие Введение в haxml , мой ответ немного запоздал, но я думаю, что в учебнике описывается, как анализировать XML, очень похожий на тот, который вы указали в своем вопросе.

Очень упрощенная реализация того, как читать XML, будет выглядеть так:

c <- fReadXml "your.xml" :: IO ANYContent
print c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...