я читал в блоге Эндрю Биркетта Аппликативные стрелки для XML &&& возвращаются к чистому , чтобы мы могли смешивать стрелки и аппликативные функторы.
Я попробовал это сам, но у меня нет того, чего я ожидаю.Мне бы хотелось получить такой результат:
[Scenario {scenario = "11111", origin = "333", alarm = "Sonde1"},
Scenario {scenario = "22222", origin = "444", alarm = "Sonde2"}]
, но вместо этого я получаю:
[Scenario {scenario = "11111", origin = "333", alarm = "Sonde1"},
Scenario {scenario = "11111", origin = "333", alarm = "Sonde2"},
Scenario {scenario = "11111", origin = "444", alarm = "Sonde1"},
Scenario {scenario = "11111", origin = "444", alarm = "Sonde2"},
Scenario {scenario = "22222", origin = "333", alarm = "Sonde1"},
Scenario {scenario = "22222", origin = "333", alarm = "Sonde2"},
Scenario {scenario = "22222", origin = "444", alarm = "Sonde1"},
Scenario {scenario = "22222", origin = "444", alarm = "Sonde2"}]
Я думаю, что в моем коде есть поворот, но я не знаю, где искать.
Ниже приведен мой код, если кто-то может предложить некоторую помощь.
{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
import Text.XML.HXT.Core
import Control.Applicative
import Text.XML.HXT.Arrow.ReadDocument
import Data.Maybe
import Text.XML.HXT.XPath.Arrows
import Text.Printf
data Scenario = Scenario
{ scenario, origin, alarm :: String
}
deriving (Show, Eq)
xml= "<DATAS LANG='en'>\
\ <SCENARIO ID='11111'>\
\ <ORIGIN ID='333'>\
\ <SCENARIO_S ERR='0'></SCENARIO_S>\
\ <SCENARIO_S ERR='2'></SCENARIO_S>\
\ <ALARM_M NAME='Sonde1'></ALARM_M>\
\ </ORIGIN>\
\ </SCENARIO>\
\ <SCENARIO ID='22222'>\
\ <ORIGIN ID='444'>\
\ <SCENARIO_S ERR='10'></SCENARIO_S>\
\ <SCENARIO_S ERR='12'></SCENARIO_S>\
\ <ALARM_M NAME='Sonde2'></ALARM_M>\
\ </ORIGIN>\
\ </SCENARIO>\
\</DATAS>"
parseXML string = readString [ withValidate no
, withRemoveWS yes -- throw away formating WS
] string
parseVal tag name = WrapArrow $ getXPathTrees (printf "/DATAS/%s" tag) >>> getAttrValue name
parseDatas = unwrapArrow $ Scenario <$> parseVal "SCENARIO" "ID"
<*> parseVal "SCENARIO/ORIGIN" "ID"
<*> parseVal "SCENARIO/ORIGIN/ALARM_M" "NAME"
testarr1= runX (parseXML xml >>> parseDatas)