Разбор внешнего документа и текущего элемента в соответствии с HXT
Обновление: теперь я решил свою главную проблему, поэтому я награжу награду хорошим обзором того, хорошее ли у меня решение или нет.
Недавно я пытался разобрать TMX- файлы, которые представляют собой XML-файлы, описывающие карты. Одним из интересных моментов в формате является то, что вы можете указать внешние наборы плиток.
Так как он уже выполнил большую часть работы, я пытался расширить htiled
библиотека, так что она обрабатывает внешние наборы плиток, но пока безуспешно.
Итак, в основном, задача, которую я пытаюсь выполнить, состоит в том, что, учитывая два документа, map.tmx
:
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="12" height="12" tilewidth="64" tileheight="64">
<tileset firstgid="1" source="ground.tsx"/>
...
</map>
а также ground.tsx
:
<?xml version="1.0" encoding="UTF-8"?>
<tileset name="ground" tilewidth="64" tileheight="64" spacing="32">
<image source="ground.png" width="64" height="64"/>
<tile id="0">
<properties>
<property name="sol" value=""/>
</properties>
</tile>
</tileset>
вернуть структуру:
Map {..., tilesets = [Tileset { name = "ground", ...}]}
Рабочий метод для анализа (только внутренний) наборов плиток:
tilesets ∷ IOSArrow XmlTree [Tileset]
tilesets = listA tileset
tileset ∷ IOSArrow XmlTree Tileset
tileset = isElem >>> hasName "tileset" >>> proc ts → do
tsName ← getAttrValue "name" ⤙ ts
tsInitialGid ← getAttrR "firstgid" ⤙ ts
tsTileWidth ← getAttrR "tilewidth" ⤙ ts
tsTileHeight ← getAttrR "tileheight" ⤙ ts
tsMargin ← arr (fromMaybe 0) . getAttrMaybe "margin" ⤙ ts
tsSpacing ← arr (fromMaybe 0) . getAttrMaybe "spacing" ⤙ ts
tsImages ← images ⤙ ts
tsTileProperties ← listA tileProperties ⤙ ts
returnA ⤙ Tileset {..}
where tileProperties ∷ IOSArrow XmlTree (Word32, Properties)
tileProperties = getChildren >>> isElem >>> hasName "tile"
>>> getAttrR "id" &&& properties
images = listA (getChildren >>> image)
Я пытался адаптировать tilesets
метод, чтобы он использовал текущий элемент или внешний документ в зависимости от source
атрибут текущего элемента, но безрезультатно:
tilesets ∷ IOSArrow XmlTree [Tileset]
tilesets = listA $ proc ts → do
source ← isElem >>> hasName "tileset" >>> getAttrValue "source" ⤙ ts
case source of
"" → tileset ⤙ ts
f → tileset ⤙ readDocument [withValidate no, withWarnings yes] f
(это одна из моих многочисленных попыток).
Обычно я достигаю точки, когда GHC говорит мне, что я не использую команду со стрелкой или что мое значение находится внутри стрелки, а это не должно. Я понимаю, что не могу выполнять ввод-вывод (и, возможно, также промежуточные операции XHT?) Прозрачным, безопасным способом, но я застрял здесь. Я действительно не уверен, как поступить.
1 ответ
Я получил его на работу с readFromDocument
а также ifA
tilesets ∷ FilePath → IOSArrow XmlTree [Tileset]
tilesets mapPath =
listA $ getChildren >>> isElem >>> hasName "tileset"
>>> getAttrR "firstgid" &&& ifA (hasAttr "source") (externalTileset mapPath) id
>>> tileset
externalTileset ∷ FilePath → IOSArrow XmlTree XmlTree
externalTileset mapPath =
arr (const (dropFileName mapPath)) &&& getAttrValue "source"
>>> arr (uncurry (</>))
>>> readFromDocument [ withValidate no, withWarnings yes ]
>>> getChildren >>> isElem >>> hasName "tileset"
tileset ∷ IOSArrow (Word32, XmlTree) Tileset
tileset = proc (tsInitialGid, ts) → do
tsName ← getAttrValue "name" ⤙ ts
tsTileWidth ← getAttrR "tilewidth" ⤙ ts
tsTileHeight ← getAttrR "tileheight" ⤙ ts
tsMargin ← arr (fromMaybe 0) . getAttrMaybe "margin" ⤙ ts
tsSpacing ← arr (fromMaybe 0) . getAttrMaybe "spacing" ⤙ ts
tsImages ← images ⤙ ts
tsTileProperties ← listA tileProperties ⤙ ts
returnA ⤙ Tileset {..}
where tileProperties ∷ IOSArrow XmlTree (Word32, Properties)
tileProperties = getChildren >>> isElem >>> hasName "tile"
>>> getAttrR "id" &&& properties
images = listA (getChildren >>> image)