유니티에서 XML파싱을 위해 WWW 클래스로 .XML 파일을 불러왔습니다. 불러들인 정보를 디시리얼라이즈하는 기능은 없나요?(안드로이드폰을 위해 개발중입니다.)


 IEnumerator read()

    {
        Text txt = GameObject.Find("ERRORMESSAGE2").GetComponent<Text>();

        string fileName = "Quests.xml";
        string filePath = "jar:file://" + Application.dataPath + "!/assets/" + fileName;

        var www = new WWW(filePath);
        yield return www;
        if (!string.IsNullOrEmpty(www.error))
        {
            txt.text = "로딩실패";
        }
        else if (string.IsNullOrEmpty(www.error))
        {
            txt.text = "로딩성공";
        }
    }

불러들였습니다만 아래 iostream같이 디시리얼라이즈 하는 기능은 없나요?

 void serialize()

{

Type[ ] questType = { typeof(QUEST) };

        XmlSerializer serializer = new XmlSerializer(typeof(QuestContainer), questType);

        TextReader textReader = new StreamReader(filePath);
        QuestContainer = (QuestContainer)serializer.Deserialize(textReader);
        textReader.Close();
        txt.text = (textReader.ReadLine());
    }

불러들인 정보를 아래 양식에 맞게 디시리얼라이즈하는 기능이 필요합니다..

정보는 불러들여진 후 각 프로쎄스로 나눠져 컨테이너로 들어가게됩니다..

public class QuestContainer
{

    private List<QUEST> confirmed = new List<QUEST>();
    private List<QUEST> complete = new List<QUEST>();
    private List<QUEST> possible = new List<QUEST>();
    private List<QUEST> im_possible = new List<QUEST>();

    public List<QUEST> Confirmed
    {
        get { return confirmed; }
        set { confirmed = value; }
    }

    public List<QUEST> Complete
    {
        get { return complete; }
        set { complete = value; }
    }

    public List<QUEST> Possible
    {
        get { return possible; }
        set { possible = value; }
    }

    public List<QUEST> im_Possible
    {
        get { return im_possible; }
        set { im_possible = value; }
    }
}
public class QUEST
{
    public string Questname { get; set; }
    public string Description { get; set; }
    public string Class { get; set; }
    public int Level { get; set; }
    public int STR { get; set; }
    public int CON { get; set; }
    public int INT { get; set; }
    public int WIS { get; set; }
    public int DEX { get; set; }
    public string Title { get; set; }
    public string Item { get; set; }
    public QUEST_TYPE questType { get; set; }
    public DIFFICULTY difficulty { get; set; }
    public EXPEDIENT eXPEDIENT { get; set; }
    public QUEST_REWARD questReward { get; set; }
    public string target { get; set; }
    public int count { get; set; }
    public bool canClear { get; set; }

    public QUEST()
    {

    }

    public QUEST(string Questname,string Description,string Class,int level,int str,int con, int Int, int wis, int dex,string title,string item,  QUEST_TYPE QuestType, DIFFICULTY Difficulty, QUEST_REWARD quest_reward, EXPEDIENT EXPEDIENT, string Target, int Count, bool canclear)
    {
        this.Description = Description;
        this.Questname = Questname;
        this.questType = QuestType;
        this.difficulty = Difficulty;
        this.eXPEDIENT = EXPEDIENT;
        this.questReward = quest_reward;
        this.Class = Class;
        this.Level = level;
        this.STR = str;
        this.CON = con;
        this.INT = Int;
        this.WIS = wis;
        this.DEX = dex;
        this.Title = title;
        this.Item = item;
        this.target = Target;
        this.count = Count;
        this.canClear = canclear;
    }
<?xml version="1.0" encoding="utf-8"?>
<QuestContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Confirmed>
    <QUEST>
      <Questname>시작</Questname>
      <Description>이제 시작이에요!</Description>
      <Class>ALL</Class>
      <Level>0</Level>
      <STR>0</STR>
      <CON>0</CON>
      <INT>0</INT>
      <WIS>0</WIS>
      <DEX>0</DEX>
      <Title />
      <Item />
      <questType>ROOP</questType>
      <difficulty>EASY</difficulty>
      <eXPEDIENT>MOVE</eXPEDIENT>
      <questReward>GOLD</questReward>
      <target>Bank</target>
      <count>10</count>
      <canClear>false</canClear>
    </QUEST>
  </Confirmed>
  <Complete />
  <Possible />
  <im_Possible />
</QuestContainer>

그런 기능이 없다면 수작업으로 주입하는 방법이라도 알려주시면 좋겠습니다.

추가사항 -

alt text

  • 2016년 06월 01일에 수정됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 모바일 게임도 조금 만들어 봤습니다.
  • 2016년 02월 15일에 작성됨

  • 수정 감사합니다.    정두식   2016.2.16 11:54     
조회수 652


4 답변


XmlSerialization을 이용하는게 좋겠네요. 안드로이드에서 loadXML()까지는 확인했고 write는 유니티에디터에서만 동작 확인해 봤습니다.

참고로 List에서 아이템을 지울때는 반복문에서 지우면 안되더군요. tmp만들어서 옮긴담에 지웠으니 코드 확인요.

using UnityEngine;
using System.Collections;
using System.Xml;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;


public class NewBehaviourScript : MonoBehaviour {
    QuestContainer container;
    void Start () {
        loadXML ();

        List<QUEST> tmp = new List<QUEST> ();
        foreach (QUEST quest in container.Confirmed) {
            container.Complete.Add (quest);
            tmp.Add (quest);
        }

        foreach (QUEST quest in tmp) {
            container.Confirmed.Remove (quest);
        }

        writeXML ();


    }

    void loadXML(){
        TextAsset textAsset = (TextAsset) Resources.Load("Catalog");  
        var serializer = new XmlSerializer(typeof(QuestContainer));
        StringReader stream = new StringReader (textAsset.ToString ());
        container = serializer.Deserialize(stream) as QuestContainer;
        stream.Close();
        Debug.Log ("Confirmed");
        foreach (QUEST quest in container.Confirmed) {
            Debug.Log (quest.Questname);
        }

        Debug.Log ("Complete");
        foreach (QUEST quest in container.Complete) {
            Debug.Log (quest.Questname);
        }                                            
    }

    void writeXML(){
        var serializer = new XmlSerializer (typeof(QuestContainer));
        var stream = new FileStream(pathForDocumentsFile("tmp.xml"), FileMode.Create);
        serializer.Serialize(stream, container);
        stream.Close();
    }

    public string pathForDocumentsFile( string filename ) 
    {
        if (Application.platform == RuntimePlatform.IPhonePlayer)
        {
            string path = Application.dataPath.Substring( 0, Application.dataPath.Length - 5 );
            path = path.Substring( 0, path.LastIndexOf( '/' ) );
            return Path.Combine( Path.Combine( path, "Documents" ), filename );
        }
        else if(Application.platform == RuntimePlatform.Android)
        {
            string path = Application.persistentDataPath; 
            path = path.Substring(0, path.LastIndexOf( '/' ) ); 
            return Path.Combine (path, filename);
        } 
        else 
        {
        string path = Application.dataPath; 
        path = path.Substring(0, path.LastIndexOf( '/' ) );
        return Path.Combine (path, filename);
        }
    }
}

수정: 더 좋은 방법 발견해서 아래 방법은 별로인것 같네요.

코드에 IEnumerator가 있는걸 보니...유니티에서 작업중이셨네요. 다음과 같이 하시면 될것 같습니다.

using UnityEngine;
using System.Collections;
using System.Xml;
using System.Collections.Generic;
public class XMLParsing : MonoBehaviour{
  QuestContainer qc;
  void Awake(){
    qc = new QuestContainer();
  }

  void parseXML(Text txt){
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(txt);
        XmlNodeList xnList; 

    //Confirmed
    xnList= xml.SelectNodes("/QuestContainer/Confirmed/QUEST");    
    foreach(XmlNode node in xnList)
    {
      Quest quest = new Quest();
      quest.QuestName = xn["QuestName"].InnerText;
      quest.Level = int.Parse(xn["Level"].InnerText);
      qc.confirmed.Add(quest);
    }

    //같은 방식으로 Complete, Possible, impossible처리
  }
}
  • 2016년 02월 15일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 모바일 게임도 조금 만들어 봤습니다.


유니티에서 파일을 불러들이시려면 Resources폴더에 파일을 넣어 두어야 합니다. Assets아래에 Resources폴더가 없으시면 만드시고, 그 안에 XML파일을 넣어두세요. 그리고 다음 코드를 참고해서 QuestContainer로 XML을 읽어들이도록 만들면 됩니다. http://www.w3schools.com/xml/cd_catalog.xml 에서 받을 수 있는 xml파일을 Resources폴더에 Catalog.xml로 넣어 두었습니다. 참고로 Resources에서 파일을 읽어올때는 확장자를 안붙여줘도 되요.

유니티에서 돌려본 코드니까 잘 될겁니다.

using UnityEngine;
using System.Collections;
using System.Xml;
using System.Collections.Generic;

public class NewBehaviourScript : MonoBehaviour {
    List<CD> confirmed= new List<CD>();

    // Use this for initialization
    void Start () {
        parseXML ();


    }

    // Update is called once per frame
    void Update () {

    }

    void parseXML(){

        TextAsset textAsset = (TextAsset) Resources.Load("Catalog");  
        XmlDocument xmlDoc = new XmlDocument ();
        xmlDoc.LoadXml ( textAsset.text );
        XmlNodeList xnList; 

        //Confirmed
        xnList= xmlDoc.SelectNodes("/CATALOG/CD");    
        foreach(XmlNode node in xnList)
        {

            CD cd = new CD();
            cd.title = node["TITLE"].InnerText;
            Debug.Log(cd.title);
            cd.artist = node["ARTIST"].InnerText;
            confirmed.Add(cd);
        }

        //같은 방식으로 Complete, Possible, impossible처리
    }
}

public class CD{
    public string title;
    public string artist;
}

질문을 올려주실때, 모두 코드로 올려주시면 더 자세히 설명이 가능할 것 같은데, XML파일은 이미지 캡쳐로 올려주시고, Quest클래스의 정의도 안올려주시니 어쩔수 없이 다른 파일을 예로 들었네요.

  • 2016년 02월 16일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 모바일 게임도 조금 만들어 봤습니다.

  • 질문에 대한 내용은 댓글로 달아주시면 좋겠습니다.    정두식   2016.2.16 11:19     
  • 알겠습니다. 이 사이트가 아직 적응이 안되서 뭐가 어떻게 돌아가는지를 모르겠네요.     정우진   2016.2.16 11:57     

TextAsset textAsset = (TextAsset) Resources.Load("Catalog");  
XmlDocument xmlDoc = new XmlDocument ();
xmlDoc.LoadXml ( textAsset.text );

이 경로가 접근이 안된다고 하셨는데요. 유니티에서 폴더 구조를 이렇게 만드신게 맞나요? Resource에 있는 모든 파일은 안드로이드로빌드 하더라도 접근이 가능합니다.

alt text

  • 2016년 02월 16일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 모바일 게임도 조금 만들어 봤습니다.

  • 질문 맨 아랫부분에 사진 추가했습니다.TextAsset textAsset = (TextAsset) Resources.Load("/xml/Catalog"); XmlDocument xmlDoc = new XmlDocument (); xmlDoc.LoadXml ( textAsset.text ); 이 되겠죠.    정우진   2016.2.16 12:26     

방금 제가 올려드렸던 코드 빌드해서 실행해보니 안드로이드에서 잘 동작합니다. Resources에 있는 내용을 TextAsset으로 읽어오는게 왜 안되는지는 잘 모르겠네요. 너무 당연히 되어야 하는 부분이라서요.

안드로이드 폰에서 돌리면서 로그 찍어본 부분 첨부합니다. Catalog.xml파일에서 Title만 Debug.Log로 찍고 있었는데 곡 이름이 찍히는게 잘 보입니다.

02-16 13:07:53.387    3637-3652/? D/Unity﹕ RGB GL_EXT_sRGB_write_control GL_EXT_texture_sRGB_decode GL_EXT_texture_filter_anisotropic GL_EXT_multisampled_render_to_texture GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_EXT_disjoint_timer_query
02-16 13:07:54.357    3637-3652/? I/Unity﹕ Empire Burlesque
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Hide your heart
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Greatest Hits
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Still got the blues
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Eros
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ One night only
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Sylvias Mother
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Maggie May
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Romanza
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ When a man loves a woman
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Black angel
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ 1999 Grammy Nominees
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ For the good times
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Big Willie style
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Tupelo Honey
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Soulsville
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ The very best of
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Stop
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Bridge of Spies
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Private Dancer
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Midt om natten
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Pavarotti Gala Concert
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ The dock of the bay
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Picture book
    (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
02-16 13:07:54.367    3637-3652/? I/Unity﹕ Red


  • 2016년 02월 16일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 모바일 게임도 조금 만들어 봤습니다.

  • xml파일을 txt파일로 바꿔주니 되네요..; 뭔 이유인지.. 답변 감사드립니다.    정우진   2016.2.16 20:00     
  • 혹시 기왕 이렇게 된거 시리얼라이즈 하는 방법도 알 수 있을 까요 ㅡ,ㅡ.. QuestContainer에 있는 리스트 별로 xml에 저장되어야 하는데, 설마 node를 하나씩 만들어서 아예 새로운 xml파일을 만들어야 하는겁니까? iostream을 이용 못하니 여간 불편한게아니네요.    정우진   2016.2.16 21:14     
  • 제 xml 파일에 있는데로 보면, 시작이라는 questname을 가진 노드를 찾아서 하위 노드들을 전부 possible로 옮긴다거나, confrim으로 옮긴다거나 하는기능이 있으면 좋을텐데요.    정우진   2016.2.16 22:40     
  • 스레드가 길어져서 첫번쨰 답변을 수정했습니다.    정두식   2016.2.17 11:33     
  • 답변 갑사드립니다. 어디서 구한 정보이신지 혹시 알 수 있으면 좋겠네요. pathForDocumentsFile에 있는 안드로이드 path는 resource인가요 streamingassets인가요?    정우진   2016.2.17 16:12     
  • 정보는 구글링해서 찾아봤어요. 이거저거의 조합이라 딱히 소스가 어딘지를 말씀드리기가 애매하네요. Unity Xml serialize로 검색했어요.안드로이드 파일이 어디 저장되는지는 저도 잘 모르겠네요.     정두식   2016.2.17 16:29     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close