2016-01-09 59 views
1

我正在使用HXT来解析简单的XML文件,并需要用默认值替换缺少的标签属性。但由于某种原因,orElse无法按预期工作。HXT使用'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"

我做错了什么?

回答

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" 

一切都很好。