Разбор внешнего документа и текущего элемента в соответствии с 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)
Другие вопросы по тегам