Shawn Hargreaves Blog
I decided to write a few posts about the role played by XML in the XNA Framework Content Pipeline, because this isn't well documented and people seem to find it confusing.
The first thing to get straight is the distinction between which things are fundamental parts of the pipeline architecture, versus which are just specific implementations for one particular type of data. Let's start with a recap of the basic pipeline architecture:
Note that there is no mention of XML in any of these steps. So at a fundamental level, XML is not part of the underlying Content Pipeline architecture.
XML enters the picture in two places:
In stage 1 of the steps described above, your file might well happen to be in XML format. If that is the case, you would want the importer in stage 2 to read XML data. There are many ways this can be achieved:
Why, given all these options, did we bother to create our own IntermediateSerializer? Weren't there enough different serializers already?
Because of the second place where the pipeline uses XML.
After the importer runs, but before the processor, we have an optional stage 2.5, where we write the data that was just loaded to an XML file in the obj directory. We do this for two reasons:
Caching is optional: importers can turn it off by setting an attribute. We disable it for our texture importer (textures are big, fast to import, and not very interesting to debug, so caching them would be a waste of time) but we do cache the outputs from our X and FBX importers.
We originally designed our IntermediateSerializer for the purpose of managing these cache files (I will explain why XmlSerializer was unsuitable in my next post). Once we had a serializer of our very own, we decided it would be useful to expose this as a public API so people could use it for other things as well. For instance:
The important thing to take away from all this is that there is nothing special or magic about our XmlImporter. This happens to be the default importer which we select when you add an XML file to your content project, but if you don't like how the IntermediateSerializer works, or want to load XML data in some other way, you can write your own importer using any of the other XML choices provided by .NET.
Also, you should note that using the XmlImporter only affects the importer stage of the pipeline. Once the data has been imported, it is just a regular managed object like any other. XML is not involved in the processor, ContentTypeWriter, .xnb, or ContentTypeReader stages.
My next couple of posts will talk about why we decided to create this new serializer, and go into more detail about how it works.
So if you imported a POX (plain ol' XML) file through the pipeline, what is the runtime equivalent? Do you still have to create your own processor? If you are loading level data, for example, you would need a LevelData processor to create a LevelData object from your XML file?
What does this give me over using XMLSerializer?
> So if you imported a POX (plain ol' XML) file through the pipeline, what is the runtime equivalent?
That depends entirely on what type you are importing. There is nothing special about the fact that the data came from an XML file: after the importer finishes, it's just data. Some data has the same type at runtime as it does at design time, while other data changes type (eg. TextureContent -> Texture).
> Do you still have to create your own processor?
That depends on whether you want to process the data or not. If it's already in the exact right format, you don't need to process it. If you want to change it in some way, you do.
Xml also comes in to play if you are messing with the content project's msbuild script or automatically generating one via code.