微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Tutorial: Loading and parsing external XML and JSON files with Unity – Part 1: XML

转载:http://blog.paultondeur.com/2010/03/23/tutorial-loading-and-parsing-external-xml-and-json-files-with-unity-part-1-xml/

As being a Flash Developer for many years,I’m very used to just quickly loading and parsing an external XML file. Although this is possible with Unity,I found out there’s very limited information about this subject available in a Unity context. While investigating this subject a while ago,I also decided to look into the JSON format as a data container,to see which works best for me. Naturally I’d prefer to use XML over JSON,but it turns out that both comes with their cons and pros,which makes it hard to say which works best.
In this two part tutorial I’ll show how you Could load an XML or JSON file into Unity and parse it’s information. Both the XML file and JSON file are containers for the same information,which makes it easier to compare the differences between the two.

XML
The XML file I’ve created contains a couple of books. In order to cover different ways to work with XML,it contains a variety of data,like attributes,regular nodes and childnodes,integers,strings and CDATA blocks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? xml version = "1.0" ?>
< books >
< book id = "1" >
< title >Papervision3D Essentials</ title >
< authors >
< author id = "1" >Paul Tondeur</ author >
< author id = "2" >Jeff Winder</ author >
</ authors >
< description >
<![CDATA[<p>Create interactive <b>Papervision3D</b> applications with stunning effects and powerful animations</p>]]>
</ description >
</ book >
< book id = "2" >
< title >Unity Game Development Essentials</ title >
< authors >
< author id = "3" >Will Goldstone</ author >
</ authors >
< description >
<![CDATA[<p>Build fully functional,professional 3D games with realistic environments,sound,<i>dynamic effects</i>,and more!</p>]]>
</ description >
</ book >
</ books >

This file can also be found on: http://paultondeur.com/files/2010/UnityExternalJSONXML/books.xml and will be loaded later on in this tutorial.

XML is not new to C#. In fact,it’s quite integrated within the language. When you create a new application in Visual Studio,you have access to the System.Xml namespace by default. Within this namespace,lots of classes can be found for creating,reading and modifying XML documents. Accessing these classes in Unity however,doesn’t work out of the Box. This is because this namespace isn’t available within Unity. The solution for this is relatively simple; We just need to reference the System.Xml dll in Unity. As Unity is build upon the Mono Framework,this file is provided with your local Unity install. You can find these files at the following locations,depending on the machine you’re running on:

  • MAC: Go to /Applications/Unity/ and right-click on Unity.app -> Show Package Contents. Then browse to “Contents/Frameworks/Mono.framework/”. In this folder you’ll find lot’s of dll files. In this case,just copy System.Xml.dll
  • Windows: Go to C:\Program Files\Unity\Editor\Data\Frameworks\Mono.framework and copy System.Xml.dll from here.

The next thing to do is paste the dll into your assets folder of a Unity project. Next time you compile this project,the System.Xml namespace is available to you from within the Unity player.

To load any external content from a webserver with Unity,we can use the WWW class. (can be compared to a URLRequest in Flash).

Once the data is loaded we can instantiate a new XML document and load the XML by the data that has returned from the www class request.

1
2
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(www.data);

Instead of using E4X (as in Flash) to select childnodes inside the XML document,we have to make use of an XPath expression. In our case we want to select all books,which are nested inside the books element. Selecting nodes returns an XmlNodeList,which will be used to loop through all results. Take a look at how to select all book nodes and loop through them:

1
2
3
4
foreach (XmlNode node in xmlDoc.SelectNodes( "books/book" ) )
{
.....
}

Inside the loop we have access to the value “node“,which contains information of the selected book. Let’s say we want to access the title node value of the book and show it on the screen:

1
Debug.Log(node.SelectSingleNode( "title" ).InnerText);

Accessing the description (which contains a CDATA block) is no different from selecting the title node:

1
Debug.Log(node.SelectSingleNode( "description" ).InnerText);

Selecting an attribute of a node works of course a bit different. When we want to access the book id attribute we do this as follows:

1
Debug.Log(node.Attributes.GetNamedItem( "id" ).Value);

All values in an XML are of a String type by default. In this case the id attribute is clearly of an integer type. Although it wouldn’t make any sense in this case,casting it to an int can be achieved by using the Convert utils class:

1
Debug.Log(Convert.ToInt16(node.Attributes.GetNamedItem( "id" ).Value));

Inside a book node,we can find an authors node,which contains nested author nodes inside. In order to loop through these,we can again use an XPath expression,only this time on the current selected node.

1
2
3
4
foreach (XmlNode author in node.SelectNodes( "authors/author" ))
{
Debug.Log(author.InnerText);
}

Around this concept of loading and parsing an XML file I’ve created a very small Unity application,which shows the two book covers on screen and calls a Debug.Log() on the author name on click on the book. The complete code can be found in the download at the bottom of this article. But the class that handles loading and parsing the XML looks as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using UnityEngine;
using System.Collections;
using System.Xml;
using System;
public class LoadXML : MonoBehavIoUr
{
IEnumerator Start()
{
//Load XML data from a URL
WWW www = new WWW(url);
//Load the data and yield (wait) till it's ready before we continue executing the rest of this method.
yield return www;
if (www.error == null )
{
//Sucessfully loaded the XML
Debug.Log( "Loaded following XML " + www.data);
//Create a new XML document out of the loaded data
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(www.data);
//Point to the book nodes and process them
ProcessBooks(xmlDoc.SelectNodes( "books/book" ));
}
else
{
Debug.Log( "ERROR: " + www.error);
}
}
//Converts an XmlNodeList into Book objects and shows a book out of it on the screen
private void ProcessBooks(XmlNodeList nodes)
{
Book book;
foreach (XmlNode node in nodes)
{
book = new Book();
book.id = Convert.ToInt16(node.Attributes.GetNamedItem( "id" ).Value);
book.title = node.SelectSingleNode( "title" ).InnerText;
book.image = node.SelectSingleNode( "image" ).InnerText;
book.description = node.SelectSingleNode( "description" ).InnerText;
book.authors = new ArrayList();
//Loop the authors
foreach (XmlNode author in node.SelectNodes( "authors/author" ))
{
book.authors.Add(author.InnerText);
}
LoadBook(book);
}
}
//Finds book object in application and send the Book as parameter.
//Currently only works with two books
private void LoadBook(Book book)
{
GameObject bookGameObject = GameObject.Find( "Book" + book.id.ToString());
bookGameObject.SendMessage( "LoadBook" ,book);
}
}

With this example you should be able to load and parse your own XML files. Before doing this,I need to point you to the fact that using the System.Xml dll results in quite a large footprint to your application. In my tests it turned out that it was about an 850kb difference between having an empty Unity application and an application that is using the System.Xml dll.

In the next part of this tutorial I’ll demonstrate how you Could achieve the same results with a JSON file as data container.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。