Xml 읽기 및 BackEnd 서버에서 내 데이터 불러오기

카드의 데이터는 xml을 통해 저장되고, 카드의 정보를 불러오는에는 카드 고유의 코드를 이용한다.

< xml 데이터 >

1.서버의 deck 데이터를 통해 xml 정보 매칭하여 카드 생성

System.xml.linq의 쿼리문을 통해 카드의 코드를 검색하여 필요한 정보만 빠르게 찾기

using System.Xml.Linq;
    public void LoadMyDeck()
    {
        deckitemBuffer = new List<Item>(50); //Item의 list 생성(덱의 카드는 50장)
        string[] type = new string[3] { "monster.xml", "magic.xml", "equip.xml" }; //xml 파일 목록
        var bro = Backend.GameData.GetMyData("character", new Where()); //내 데이터 서버에서 불러오기
        var keys = bro.Rows()[0]["deck"][0].Keys; //내 데이터 중 deck 데이터 가져오기
        foreach (var key in keys) // 내 deck 데이터를 하나씩 돌면서
        {
            if (key.Substring(0, 1) == "1") //카드 code의 첫 숫자가 1이면 몬스터, 2라면 마법, 3이라면 장비 
            {
                XDocument document = XDocument.Load(@"C:\nexon_maplestory_battle_monsters_league_s\Assets\Resources\CARD\xml\" + type[0]); //해당 폴더에 들어있는 몬스터 xml 불러오기
                var books = from row in document.Descendants("row")
                            where (row.Element("CODE").Value == key) //row의 code가 key(deck 요소의 code)값과 같은 항목
                            select new // 그중에서 아래의 항목들을 가져온다.
                            {
                                name = row.Element("NAME").Value,
                                grade = row.Element("GRADE").Value,
                                cost = row.Element("COST").Value,
                                att = row.Element("ATT").Value,
                                def = row.Element("DEF").Value,
                                abl = row.Element("ABL").Value,
                                code = row.Element("CODE").Value,
                                area = row.Element("AREA").Value,
                                ablcode = row.Element("ABLCODE").Value,
                                link = row.Element("LINK").Value
                            };
                for (int i = 0; i < int.Parse(bro.Rows()[0]["deck"][0][key][0].ToString()); i++)
                {
                    foreach (var row in books) //Item을 생성하여, Item의 정보를 채워서 list에 추가
                    {
                        Item item = new Item();
                        item.name = row.name;
                        item.grade = int.Parse(row.grade);
                        item.cost = Resources.Load<Sprite>("CARD/num/" + row.cost);
                        item.cost_num = int.Parse(row.cost);
                        item.attack = int.Parse(row.att);
                        item.health = int.Parse(row.def);
                        item.abl = row.abl;
                        item.code = int.Parse(row.code);
                        item.main = Resources.Load<Sprite>("CARD/monster/" + row.code);
                        item.background = Resources.Load<Sprite>("CARD/background/" + row.area);
                        item.cardbase = card_base_mon[item.grade];
                        item.ablcode = row.ablcode;
                        item.link = row.link;
                        deckitemBuffer.Add(item);
                    }
                }
            }
        }
    }

위의 방법은 code만 순서 없이 나열되어 있을 때 주로 사용하는 방법이다. 위의 Item class는 카드와 entity의 바탕이 된다.
아래의 코드는 도감과 같이 xml을 모두 확인할 때 사용한다.

using System.Xml;
    public void LoadAllBook()
    {
        TextAsset textAsset = (TextAsset)Resources.Load("CARD/xml/monster");
        //Text Assets은 프로젝트 안의 여러 텍스트 파일을 텍스트 에셋 형식으로 변환한다.(변환 지원 파일 : txt,html,xml,bytes,json,csv,yaml,fnt)
        XmlDocument xmlDoc = new XmlDocument(); //xml을 불러올 수 있다.
        xmlDoc.LoadXml(textAsset.text); //xml의 형식의 파일의 텍스트 에셋을 불러온다.
        XmlNodeList nodes = xmlDoc.SelectNodes("rows/row");
        foreach (XmlNode node in nodes) //xml의 모든 row를 하나씩 for 문을 돈다.
        {
            Item item = new Item();
            item.name = node.SelectSingleNode("NAME").InnerText; //row에서 이름이 "NAME"인 노드 안의 TEXT를 가져온다.(string 형식)
            item.grade = int.Parse(node.SelectSingleNode("GRADE").InnerText);
            item.cost = Resources.Load<Sprite>("CARD/num/" + node.SelectSingleNode("COST").InnerText);
            item.cost_num = int.Parse(node.SelectSingleNode("COST").InnerText);
            item.attack = int.Parse(node.SelectSingleNode("ATT").InnerText);
            item.health = int.Parse(node.SelectSingleNode("DEF").InnerText);
            item.abl = node.SelectSingleNode("ABL").InnerText;
            item.code = int.Parse(node.SelectSingleNode("CODE").InnerText);
            item.main = Resources.Load<Sprite>("CARD/monster/"+node.SelectSingleNode("CODE").InnerText);
            item.background = Resources.Load<Sprite>("CARD/background/"+node.SelectSingleNode("AREA").InnerText);
            item.cardbase = card_base_mon[item.grade];
            item.ablcode = node.SelectSingleNode("ABLCODE").InnerText;
            allBookMon.Add(item);
        }
    }

linq와 loop문에서의 항목이 많지 않은 이상 큰 차이가 없다.(환경에 따라 다름) 여러 포럼을 찾아보면 c#에서는 loop문이 좀 더 빠르다고는 한다. 하지만, code를 작성할 때에는 linq가 더 간결하기에 위의 항목에 linq를 사용하였다. 추가적인 post로 직접 속도를 비교해 보도록 할 예정이다.