我正在使用HXT解析一个简单的XML文件,并且需要使用默认值替换标记的缺失属性。但由于某些原因,orElse
无法正常工作。
以下是XML文件:
<!-- window_home.xml -->
<elements>
<Window libraryItemName="panel_tabs" name="panel_tabs" selected="true">
<matrix>
<Matrix ty="-11.8" />
</matrix>
</Window>
<Window libraryItemName="home_powerup_menu" name="home_powerup_menu" selected="true">
<matrix>
<Matrix tx="12.4" />
</matrix>
</Window>
<Window libraryItemName="panel_name" name="panel_name" selected="true">
<!-- data here -->
</Window>
</elements>
有问题的标签是Matrix
。
以下是我的代码:
{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
import Text.XML.HXT.Core
parseXML = readDocument [ withValidate no
, withRemoveWS yes -- throw away formating WS
]
atTag tag = deep (isElem >>> hasName tag)
data XflMatrix = XflMatrix { a, b, c, d, tx, ty :: Float } deriving (Show)
initXflMatrix = XflMatrix { a = 1.0, d = 1.0, b = 0.0, c = 0.0, tx = 0.0, ty = 0.0 }
data UiWindow = UiWindow {
wndName :: String,
wndNameLib :: String,
wndMatrix :: XflMatrix,
wndChildren :: [UiWindow]
} deriving (Show)
initUiWindow = UiWindow {
wndName = "empty",
wndNameLib = "",
wndMatrix = initXflMatrix,
wndChildren = []
}
parseDoc docName = runX $ parseXML fileName >>> getWindow
where
fileName = docName ++ ".xml"
getMatrixFromTag = atTag "Matrix" >>> proc x -> do
tx <- getFloatAttrib "tx" -< x
ty <- getFloatAttrib "ty" -< x
returnA -< initXflMatrix { tx = read tx :: Float, ty = read ty :: Float }
where
--getFloatAttrib attribName = getAttrValue attribName
getFloatAttrib attribName = getAttrValue attribName `orElse` constA "0.0"
getWindow = atTag "Window" >>> proc x -> do
libraryItemName <- getAttrValue "libraryItemName" -< x
name <- getAttrValue "name" -< x
m <- getMatrixFromTag -< x
children <- arrIO parseDoc -< libraryItemName
returnA -< initUiWindow { wndName = name, wndNameLib = libraryItemName, wndChildren = children, wndMatrix = m}
documentName = "DOMDocument.xml"
parseRoot = parseXML documentName
--runX (parseRoot >>> getWindow )
看起来像
行getFloatAttrib attribName = getAttrValue attribName `orElse` constA "0.0"
不返回"0.0"
。
我做错了吗?
答案 0 :(得分:2)
好的,那太愚蠢了。 我应该检查一下类型:
λ: :t getAttrValue
getAttrValue :: ArrowXml a => String -> a XmlTree String
λ: :t hasAttr
hasAttr :: ArrowXml a => String -> a XmlTree XmlTree
现在,在将有问题的行更改为:
之后getFloatAttrib attribName = (hasAttr attribName >>> getAttrValue attribName) `orElse` constA "0.0"
一切都很好。