BoardGameGeek i model XML

Ostatnio rozpoczęłam integrację mojej aplikacji z serwisem BoardGameGeek (udostępnia on swoje API). Przygotowałam się, zrobiłam research i zabrałam się do kodowania. Wysłanie requesta to sprawa prosta, teraz pytanie, co zrobić z response? Na początek muszę znaleźć daną grę podając jej nazwę. Wysyłam więc do BGG przykładowe zapytanie:

BGGgetResult.PNG

Wszystko pięknie, tylko teraz z odpowiedzi muszę wygrzebać objectid tej gry (w naszym przypadku 120677), żeby później pobrać jej szczegółowe parametry. Aktualnie pobieram body odpowiedzi jako string.  Wychodzi więc na to, że muszę ją rzutować na konkretny model – czyli czas na zabawę z XMLem. Z Jsonem byłoby łatwiej, ale niestety api json jest dopiero w powijakach. Na ten moment muszę zadowolić się XMLem.

Utwórzmy metodę GetBoardGameObject(), do której przekażemy pobrane body jako string i spróbujemy go zdeserializować na obiekt boardgames:

public static BoardGame GetBoardGameObject(string BGGBoardGameStr)
{
 object boardGamesObject = new Models.boardgames();

 XmlSerializer xmlSerializer = new XmlSerializer(typeof(Models.boardgames));
 using (TextReader textReader = new StringReader(BGGBoardGameStr))
 {
 var boardGamesObject = xmlSerializer.Deserialize(textReader);
 }
 //...
}

Niestety XmlSerializer wymaga podania typu zmiennej, na którą ma rzutować string. Trzeba więc utworzyć dokładnie taki sam model jak ten zwracany przez BGG w XML. Można to robić na piechotę samodzielnie – wg mnie łatwo o pomyłkę, nawet jeśli ktoś wie, z której strony się za to zabrać. I tutaj pomoc oferuje VS – pozwala automatycznie wygenerować model na podstawie obiektu XML. Jak? Sprawdźmy. Przykładowy zwrócony XML wygląda następująco:

<boardgames termsofuse="http://boardgamegeek.com/xmlapi/termsofuse">
<boardgame objectid="120677">
<name primary="true">Terra Mystica</name>
<yearpublished>2012</yearpublished>
</boardgame>
<boardgame objectid="149890">
<name primary="true">Terra Mystica: 4 Town Tiles</name>
<yearpublished>2013</yearpublished>
</boardgame>
<boardgame objectid="181289">
<name primary="true">Terra Mystica: Big Box</name>
<yearpublished>2015</yearpublished>
</boardgame>
<boardgame objectid="150740">
<name primary="true">Terra Mystica: Bonus Card Shipping Value</name>
<yearpublished>2013</yearpublished>
</boardgame>
<boardgame objectid="184895">
<name primary="true">Terra Mystica: Erweiterungsbogen</name>
<yearpublished>2015</yearpublished>
</boardgame>
<boardgame objectid="161317">
<name primary="true">Terra Mystica: Fire &amp; Ice</name>
<yearpublished>2014</yearpublished>
</boardgame>
<boardgame objectid="220308">
<name primary="true">Terra Mystica: Gaia Project</name>
<yearpublished>2017</yearpublished>
</boardgame>
</boardgames>

Widać, że mamy element boardgames, który składa się z atrybutu termsofuse i wielu elementów boardgame. Pojedynczy element boardgame ma atrybut objectid, oraz elementy: name i yearpublished. Element name dodatkowo ma atrybut primary.

Struktura jest trochę złożona, jak utworzyć dla niej model? Na początku utwórzmy pusty plik o nazwie boardgames zawierający tylko przestrzeń nazw:

namespace BoardGameGeekIntegration.Models
{
}

i zostawmy kursor w jego ciele. Następnie skopiujmy do schowka cały wypisany wyżej kod XML i wybierzmy z paska narzędzi VS opcję Edit => Paste Special => Paste XML As Classes.

pasteXmlAsClasses.PNG

Jaki mamy wynik?

xmlClass.PNG

Wynik to klasa modelu, która zawiera ponad 100 linii kodu. Wow, a wszystko to automatycznie!

Dzięki temu w szybki sposób otrzymaliśmy model z BGG w naszej aplikacji i możemy na nim operować, pobierając wartości np. konkretnych atrybutów. Nie trzeba męczyć się z odwzorowaniem w naszej aplikacji modelu z BGG.

Jedna uwaga do wpisu “BoardGameGeek i model XML

  1. Pingback: BoardGamesNook: moduł gier planszowych – programmer-girl

Dodaj komentarz