Content pipeline xml stuff

Hey!
I’ve been messing with creating a save game file and loading items for my game from XML files. I managed to get it working using an xml serializer, but I just noticed there is an option to load XML files using the content pipeline?
I’ve been searching for a couple of hours now and i just cant find anything on how to do it.
Basically what I want to do is to load/save lists of objects from XML files and then write them to XML files.
I tried just putting my existing files into the pipeline, but I get an error, that it doesn’t find xna xml stuff in my .xml files.
Is there any documentation on the internet that I have missed or any examples I can take a look at? Does the Monogame Pipeline work the same as the XNA pipeline? (i found some documentation for that)
Thanks!!

I have a project that loads from xml files. I’m finding it now, and I’ll get back to you soon.

I would really appreciate that! You’re awesome! :smiley:

ok, when you drag your xml files into the solution explorer, have you set them to content copy if newer…?

…Heres all I have in my load section:

using System.Xml;

// I just load a document:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(".\Content\Terrain\Terrain.xml");

// then I set variables in my game from entries in that document:
terrain_types.Last().base_row = Convert.ToInt32( t_type.SelectSingleNode(“base_y”).InnerText);

Wait, have I been doing this wrong the whole time? x: I havent put the files into the solution explorer, I just had them on my drive in the debug folder …
Anyway I’ve been using this for creating the file:

XmlSerializer serializer = new XmlSerializer(typeof(List<Item>));
FileStream fs = new FileStream(xmlFilePath, FileMode.Create);
TextWriter writer = new StreamWriter(fs, new UTF8Encoding());
serializer.Serialize(writer, _itemList);
writer.Close();

and this for reading from the file:

XDocument document = XDocument.Load(_xmlItems);
string xml = document.ToString();

XmlSerializer serializer = new XmlSerializer(typeof(List<Item>));
StringReader reader = new StringReader(xml);
object obj = serializer.Deserialize(reader);
_items = (List<Item>)obj;
reader.Close();

Which looks similar to what you have…
When i put the xml files created form the code above into the Pipeline, and build it, i get an error:

error: Importer ‘XmlImporter’ had unexpected failure!
Microsoft.Xna.Framework.Content.Pipeline.InvalidContentException: Could not find XnaContent element in …

So i guess i have to put the files into the solution explorer and just change their paths to “.\Content*.xml”?

yeah, xDoc.Load(".\Content\Terrain\Terrain.xml"); // or whatever applies to you

What does a serializer do? Compared to just loading values like I do, one item at a time?

Well it creates an xml version of the object or whatever you put in, so in my case it creates:
(replacing < and > because it doesnt like them here)

ArrayOfItem xmlns:xsi .....
    Item
        ID 12 /ID
        position 
            x 12 /x
            y 2 /y
        /position
    /item

And it does that for the whole list of objects (in my case), so i can read/recreate the whole list later.
Hope you understand :slight_smile: (it took me like a week to get this to work haha)

yeah, thanks! That does sound pretty nice… Did you get the loader to work?

Yup just changed the positions to .\Content\xmlfile.xml and added the files to solution.
Theres an option in the pipeline tool for xml files, will have to find out what that does :stuck_out_tongue: It might just be a better way to handle save files!
Thanks for your help!!

Apologies for coming to this thread late - I’m just looking into putting XML in the content pipeline. The error your getting I believe is because the XML doesn’t contain the below elements - I created a blank xml file VIA the content pipeline app and it looks like the below: (brackets removed of course)

?xml version="1.0" encoding="utf-8"?
XnaContent xmlns:ns="Microsoft.Xna.Framework"
   Asset Type="Object"
  /Asset
/XnaContent

This xml file built ok and created a .xnb file in the content output folder - however I’m not sure how to read/write to that file yet (still messing around).

As for general xml - yes I can serialise the objects to xml and deserialise them back into object as @bambucha explains - this method I think is fine for save/loading game data - where I want to use the content pipline to store fixed game data.

I’m using the MG 3.5 pipeline so if anyone has any info on how to read/right to it, please let us know. I did find this link: http://dylanwilson.net/creating-custom-content-importers-for-the-monogame-pipeline but it seems to be a bit long for reading /writing data, though I’ve not gone over it yet.

@Harag Hey!

I’ve never got what you mentioned to work… I tried to figure it out for a few days with no luck, so I just added the xml files to the solution in the Content folder and loaded the files using XDocument…
I’m ok with using this method, but the problem is that the files are not encrypted, so anyone can see them… I tried encrypting them, but I couldn’t figure out how to read the files back.
Also I should mention that I just started using C# and MonoGame a couple of months ago, so I’m still learning…

I also remember getting the same error as you and I think thats the place I got stuck at aswell.

Let me know if you figure something out!! Would really appreciate it :slightly_smiling:

@bambucha I’ve managed to get it working to read in an XML file that has been built using the pipeline (XNB) so that’s now a binary file - however it’s only good for reading as far as I can tell and you can’t write out to this format in your game - e.g. like a save game option, So it’s useful for things like Level data, or starting data - or an RPG equipment stats - the sort of stuff that won’t change.

You need to have your class in a separate dll project and reference it in the pipe line application. Here is my class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;

namespace Project1.Shared.Entities
{
[Serializable]
public class HistoryRegion
{
public string Key;
public int X;
public int Y;

	[XmlElement("Color")]
	public Color Color;

	public HistoryRegion()
	{
	}

	public HistoryRegion(string key, int x, int y, Color regionColor)
	{
		Key = key;
		X = x;
		Y = y;
		Color = regionColor;
	}
}

}

Here is the XML (brackets removed) I have in the content folder - Notice the Asset TYPE on the 3rd line!

?xml version=“1.0” encoding=“utf-8”?
XnaContent xmlns:ns=“Microsoft.Xna.Framework”
Asset Type=“System.Collections.Generic.List[Project1.Shared.Entities.HistoryRegion]”
Item Key1/Key X1 /X Y1 /Y Color 000066FF /Color /Item
Item Key1/Key X35 /X Y32 /Y Color FFFFFFFF /Color /Item
Item Key2/Key X32 /X Y62 /Y Color FFFFFFFF /Color /Item
/Asset
/XnaContent

I’ve recently posted a thread about the issues I was having up until this point, but actually have it building and loading the data now :slight_smile:

Building XML in Content Pipeline