解析其他 XML 文件,同时使用 HXT 解析树
Parse other XML files whilst parsing tree with HXT
我正在解析 XML 描述游戏用户界面的文件,同时尝试学习 HXT。
我可以成功解析单个 XML 文件。但无法确定在 getWindow
函数内打开和解析其他 XML 文件的最佳方式是什么。
每个 XML 由 Window
个组成。每个 Window
有 name
和 libraryName
。后者是描述 window 的 XML 文件的名称。
例如,根看起来像这样:
<!-- DOMDocument.xml -->
<elements>
<Window libraryItemName="window_home" name="window_home">
<!-- data here -->
</Window>
<Window libraryItemName="window_battle" name="window_battle">
<!-- data here -->
</Window>
</elements>
然后每个 window 都有一个单独的 XML 文件。例如。 "window_home":
<!-- window_home.xml -->
<elements>
<Window libraryItemName="panel_tabs" name="panel_tabs" selected="true">
<!-- data here -->
</Window>
<Window libraryItemName="home_powerup_menu" name="home_powerup_menu" selected="true">
<!-- data here -->
</Window>
<Window libraryItemName="panel_name" name="panel_name" selected="true">
<!-- data here -->
</Window>
</elements>
我用这段代码解析根 DOMDocument.xml
:
{-# 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 UiWindow = UiWindow {
wndName :: String,
wndNameLib :: String,
wndChildren :: [UiWindow]
} deriving (Show)
initUiWindow = UiWindow {
wndName = "empty",
wndNameLib = "",
wndChildren = []
}
getWindow = atTag "Window" >>>
proc x -> do
_libraryItemName <- getAttrValue "libraryItemName" -< x
_name <- getAttrValue "name" -< x
-- TODO: Open _libraryItemName XML file and parse windows in it
returnA -< initUiWindow { wndName = _name, wndNameLib = _libraryItemName}
documentName = "DOMDocument.xml"
parseRoot = parseXML documentName
--runX (parseRoot >>> getWindow )
由于 getWindow
函数未包含在 IO
中,因此实现所需行为的最佳方法是什么?
HXT 组合器是多态的,并且有一种类型 IOLA
which implements all the XML parsing-relevant typeclasses, in addition to ArrowIO
可以执行 IO
中箭头。
例如,如果你想对文件进行完全递归解析,你可以做一些简单的事情
parseDoc docName = runX $ parseXML fileName >>> getWindow
where
fileName = docName ++ ".xml"
getWindow = atTag "Window" >>> proc x -> do
libraryItemName <- getAttrValue "libraryItemName" -< x
name <- getAttrValue "name" -< x
children <- arrIO parseDoc -< libraryItemName
returnA -< initUiWindow { wndName = name, wndNameLib = libraryItemName, wndChildren = children}
我正在解析 XML 描述游戏用户界面的文件,同时尝试学习 HXT。
我可以成功解析单个 XML 文件。但无法确定在 getWindow
函数内打开和解析其他 XML 文件的最佳方式是什么。
每个 XML 由 Window
个组成。每个 Window
有 name
和 libraryName
。后者是描述 window 的 XML 文件的名称。
例如,根看起来像这样:
<!-- DOMDocument.xml -->
<elements>
<Window libraryItemName="window_home" name="window_home">
<!-- data here -->
</Window>
<Window libraryItemName="window_battle" name="window_battle">
<!-- data here -->
</Window>
</elements>
然后每个 window 都有一个单独的 XML 文件。例如。 "window_home":
<!-- window_home.xml -->
<elements>
<Window libraryItemName="panel_tabs" name="panel_tabs" selected="true">
<!-- data here -->
</Window>
<Window libraryItemName="home_powerup_menu" name="home_powerup_menu" selected="true">
<!-- data here -->
</Window>
<Window libraryItemName="panel_name" name="panel_name" selected="true">
<!-- data here -->
</Window>
</elements>
我用这段代码解析根 DOMDocument.xml
:
{-# 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 UiWindow = UiWindow {
wndName :: String,
wndNameLib :: String,
wndChildren :: [UiWindow]
} deriving (Show)
initUiWindow = UiWindow {
wndName = "empty",
wndNameLib = "",
wndChildren = []
}
getWindow = atTag "Window" >>>
proc x -> do
_libraryItemName <- getAttrValue "libraryItemName" -< x
_name <- getAttrValue "name" -< x
-- TODO: Open _libraryItemName XML file and parse windows in it
returnA -< initUiWindow { wndName = _name, wndNameLib = _libraryItemName}
documentName = "DOMDocument.xml"
parseRoot = parseXML documentName
--runX (parseRoot >>> getWindow )
由于 getWindow
函数未包含在 IO
中,因此实现所需行为的最佳方法是什么?
HXT 组合器是多态的,并且有一种类型 IOLA
which implements all the XML parsing-relevant typeclasses, in addition to ArrowIO
可以执行 IO
中箭头。
例如,如果你想对文件进行完全递归解析,你可以做一些简单的事情
parseDoc docName = runX $ parseXML fileName >>> getWindow
where
fileName = docName ++ ".xml"
getWindow = atTag "Window" >>> proc x -> do
libraryItemName <- getAttrValue "libraryItemName" -< x
name <- getAttrValue "name" -< x
children <- arrIO parseDoc -< libraryItemName
returnA -< initUiWindow { wndName = name, wndNameLib = libraryItemName, wndChildren = children}