- Home /
XML Check if a node exists
I have set up an XML in which I will write data. Each node is unique, like this:
<transforms>
<Exterieur>
<MurExterieur> BriqueViolette </MurExterieur>
</Exterieur>
<Interieur>
<MurInterieur> Texture </MurInterieur>
</Interieur>
</transforms>
I can not do:
-When I edit the XML file, I must see if the node is already exists,
If there is, I do not create the node, but I write in,
If there is, I create and write in.
My problem is that I can not retrieve the node. I try with this method:
XmlElement = elmExistorNot xmlDoc.GetElementById (rootNodeName);
=> I get reference "null"
and the second uses an array of Nodes, or I'm sure each of my nodes will be unique ...
Need help :]
Answer by CHPedersen · Sep 01, 2011 at 10:46 AM
Your approach is actually not too far off the mark, but you're using the wrong getelement method. GetElementById searches for an attribute called ID, and then attempts to match the argument up against it. It returns null for you, because your XML doesn't have any nodes with an ID attribute with a name corresponding to the rootNodeName.
Instead, use XmlDocument.GetElementsByTagName, see this link:
http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.getelementsbytagname.aspx
It returns a list of all elements whose tagname is what you provide, and since you mentioned that all your nodes have unique tag names, the returned array will always have length = 1 if the element already exists, and the node you want will always be at index = 0 if it exists. If the returned array has length = 0, it's because the node doesn't exist and you can go ahead and create it.
Answer by thor_tillas · Sep 01, 2011 at 11:02 AM
Hi,
As I see it, you have to do something like that :
public void ReadXmlSettings()
{
System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load("myXmlSettings.xml");
// Get the root element (which is "transforms" in your case).
System.Xml.XmlElement root = xmlDocument.DocumentElement;
// Get the Exterieur element or create it when does not exist.
System.Xml.XmlElement exterieurElement = this.GetChildByName(root, "Exterieur", xmlDocument);
// Get the Interieur element or create it when does not exist.
System.Xml.XmlElement interieurElement = this.GetChildByName(exterieurElement, "Interieur", xmlDocument);
// Do something with interieur element...
}
private System.Xml.XmlElement GetChildByName(System.Xml.XmlElement parent, string childName, System.Xml.XmlDocument xmlDocument)
{
// Try to find it in the parent element.
System.Xml.XmlElement childElement = parent.SelectSingleNode(childName) as System.Xml.XmlElement;
if (null == childElement)
{
// The child element does not exists, so create it.
childElement = xmlDocument.CreateElement(childName);
parent.AppendChild(childElement);
}
return childElement;
}
Does it correspond to your need ?
Otherwise, you can create a "Settings" class and serialize/deserialize it with the Serializer class. Here is the MSDN documentation about it : http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx
It's pretty simple to use and it's work well for simple serialization.
Cheers !
Answer by thor_tillas · Sep 01, 2011 at 01:00 PM
You have many ways to doing so. But if your goal is to get some "Settings" on the begining of your game, I really suggest you to look after the Serializer stuff. All you need is a Class which describe your settings as "Properties" and add these line where you need to get the settings back from XML.
XmlSerializer serializer = new XmlSerializer(typeof(SettingsClass));
System.IO.FileStream fs = new System.IO.FileStream(xmlPath, System.IO.FileMode.Open);
SettingsClass settings = (SettingsClass)serializer.Deserialize(fs);
If you want to create the xml based on the class :
SettingsClass settings = new SettingsClass();
XmlSerializer serializer = new XmlSerializer(typeof(SettingsClass));
System.IO.FileStream fs = new System.IO.FileStream(xmlPath, System.IO.FileMode.Create);
serializer.Serialize(fs, settings);
I don't know if it's a correct solution for your case, but it seams to me a more developper friendly way to get some settings saved.
I hope it can help...
Cheers !
Now I need to read all the xml node after node, for that I must target the nodes one after the other and get their content.
In my view, be there a method to move the nodes one after the other, or I must stock every node name in a table to go with getElementByTagName. Can someone enlighten me :]]?
Thank you very much everyone for all the quick answers. I seek and I find a way to do that work (the goal is to store textures and the object on which it is applied in order to transfer it to another model):
if(File.Exists (filepath))
{
xmlDoc.Load(filepath);
XmlNodeReader xmlReader = new XmlNodeReader(xmlDoc);
while (xmlReader.Read()) {
xmlValue = xmlReader.Value;
if(xmlReader.Name != "") {
xmlName = xmlReader.Name;
} if(xmlReader.HasValue) {
Texture2D txtrLoader = Resources.Load("Texture/"+xmlValue, typeof(Texture2D)) as Texture2D;
Transform sousObject = targetHouse.transform.FindChild(xmlName);
sousObject.renderer.material.mainTexture = txtrLoader; }
}
}
I would like you to tell me if the "serializer" you speak of is more optimize or perform?!
No, I think it's clearly less optmized. The serializer need to get the class properties by reflection and then set them some value. But it allows to keep a code more clean in certain case.
I think your solution is well adapted to your needs.
Your answer
Follow this Question
Related Questions
Write and Read to a iOS device! Help 1 Answer
Xml Serialization? (how to read/write?) 1 Answer
A node in a childnode? 1 Answer
Reading XML Data C# 2 Answers
Read STRING AS XML TO SHOW LIST 1 Answer