- Home /
How to edit a list element in an XML file
Introduction
In my game players are able to place magazine pouches on a combat vest. I want to save this data so it can be loaded later.
Each pouch has a name, three position floats and three rotation floats.
The number of pouches can vary, which is why their data needs to be in a list.
The vest only has a name.
"Loadout" is a word I use to describe what equipment the player is wearing. Later helmets, belts, holsters etc. will be added.
First question
How can I edit the name, positions and rotation of each pouch? I can add pouches, but I don't know how to edit them.
Second question
How can I make the attribute of the vest show correctly? Currently it is showing as an attribute of the root element "Loadout".
My C# script containing the data for the XML file
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using UnityEngine;
using UnityEditor;
[XmlRoot("Loadout")]
[XmlInclude(typeof(Pouch))]
public class Loadout {
[XmlAttribute("vestName")]
public string vestName;
[XmlArray("Vest")]
[XmlArrayItem("pouch")]
public List<Pouch> vestPouches = new List<Pouch>();
}
[XmlType("Pouch")]
public class Pouch {
// The type of pouch
[XmlAttribute("pouchName")]
public string pouchName;
// Position of the pouch
[XmlElement("posX")]
public float posX;
[XmlElement("posY")]
public float posY;
[XmlElement("posZ")]
public float posZ;
// Rotation of the pouch
[XmlElement("rotX")]
public float rotX;
[XmlElement("rotY")]
public float rotY;
[XmlElement("rotZ")]
public float rotZ;
}
My C# script that creates the XML file and edits the variables
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using UnityEngine;
public class xmlTestWriter : MonoBehaviour {
public string nameOfLoadout;
void Start () {
SaveData ();
}
void SaveData () {
XmlSerializer mySerializer = new XmlSerializer (typeof(Loadout));
string path = "Assets/_Game/Resources/Loadouts/" + nameOfLoadout + ".xml";
StreamWriter myWriter = new StreamWriter (path);
Loadout newLoadout = new Loadout ();
newLoadout.vestName = "Combatvest03";
newLoadout.vestPouches.Add (new Pouch ());
newLoadout.vestPouches.Add (new Pouch ());
newLoadout.vestPouches.Add (new Pouch ());
mySerializer.Serialize (myWriter.BaseStream, newLoadout);
myWriter.Close ();
}
}
The produced XML file
<?xml version="1.0" encoding="Windows-1252"?>
<Loadout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" vestType="Combatvest03">
<Vest>
<pouch>
<posX>0</posX>
<posY>0</posY>
<posZ>0</posZ>
<rotX>0</rotX>
<rotY>0</rotY>
<rotZ>0</rotZ>
</pouch>
<pouch>
<posX>0</posX>
<posY>0</posY>
<posZ>0</posZ>
<rotX>0</rotX>
<rotY>0</rotY>
<rotZ>0</rotZ>
</pouch>
<pouch>
<posX>0</posX>
<posY>0</posY>
<posZ>0</posZ>
<rotX>0</rotX>
<rotY>0</rotY>
<rotZ>0</rotZ>
</pouch>
</Vest>
</Loadout>
And this is what I would like the XML file to be like
<Loadout>
<Vest vestType="Combatvest03">
<pouch pouchType="m4x1 Pouch">
<posX>0</posX>
<posY>0</posY>
<posZ>0</posZ>
<rotX>0</rotX>
<rotY>0</rotY>
<rotZ>0</rotZ>
</pouch>
</Vest>
</Loadout>
Final note
I have been working on this for several weeks. I have watched and read a lot of video and text tutorials about xml creation. I even had some of them work, but when I put it into my own work it all breaks apart!
I really hope someone can help me.
Thank you in advance! :)
Answer by falle1234 · Oct 12, 2017 at 11:46 AM
I have expanded your LoadOut class a little, but it gets the job done :) I also added some serialization code that lets you control the output a little easier.
LoadOut, Vest and Pouch classes
using System.Collections.Generic;
using System.Xml.Serialization;
public class LoadOut
{
public Vest Vest { get; set; } = new Vest();
}
public class Vest
{
[XmlAttribute("vestType")]
public string vestName;
[XmlElement("pouch")]
public List<Pouch> VestPouches = new List<Pouch>();
}
public class Pouch
{
public float posX;
public float posY;
public float posZ;
[XmlAttribute("pouchType")]
public string pouchName;
public float rotX;
public float rotY;
public float rotZ;
}
Serialization code
using System.Text;
using System.Xml;
using System.Xml.Serialization;
internal class Program
{
private static void Main(string[] args)
{
var sb = new StringBuilder();
// The settings keep indentation but strips the xmlDeclaration
var settings = new XmlWriterSettings {OmitXmlDeclaration = true, Indent = true};
// Creates a writer using the above settings
var writer = XmlWriter.Create(sb, settings);
var serializer = new XmlSerializer(typeof(LoadOut));
var load = new LoadOut();
load.Vest.vestName = "Combatvest03";
load.Vest.VestPouches.Add(new Pouch {pouchName = "m4x1 pouch"});
// Create namespaces and add an empty default namespace
var namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
// Serialize using the xmlwriter and the stripped namespaces
serializer.Serialize(writer, load, namespaces);
Console.Write(sb.ToString());
Console.ReadKey();
}
}
I merged your code with my own and now it works. Thank you!
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
How do I save a List in my project? 0 Answers
Creating a custom List or Collection 1 Answer
TargetRpc not sending atribute (Mirror) 0 Answers