Beruflich Dokumente
Kultur Dokumente
Deserializing Individual
Elements in XML Documents
Version 1.0
Thomas Manson (thomas.manson@charteris.com)
12 May 2003
Using XSD.exe to generate the required classes results in the following classes for the
PropertyExchangeType, the AgentType and the PropertyType types (the complete
sample application source code can be downloaded from
http://www.charteris.com/Publications/WhitePapers/Downloads/PropertyExchange.
zip).
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="www.charteris.
com/namespaces/propertyexchange")]
[System.Xml.Serialization.XmlRootAttribute("PropertyExchange",
Namespace="www.charteris.com/namespaces/propertyexchange",
IsNullable=false)]
public class PropertyExchangeType {
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("Agent",
IsNullable=false)]
public AgentType[] Agents;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("Property",
IsNullable=false)]
public PropertyType[] Properties;
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="www.charteris.
com/namespaces/propertyexchange")]
/// <remarks/>
public string AgentID;
/// <remarks/>
public string Name;
/// <remarks/>
public AddressType Address;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public Action action;
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace="www.charteris.
com/namespaces/propertyexchange")]
public class PropertyType {
/// <remarks/>
public string PropertyID;
/// <remarks/>
public string OwningAgentID;
/// <remarks/>
public AddressType Address;
/// <remarks/>
public int Price;
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool PriceSpecified;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType="date")]
public System.DateTime DateListed;
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool DateListedSpecified;
/// <remarks/>
public PropertyTypePropertyDetails PropertyDetails;
/// <remarks/>
public PropertyTypeViewings Viewings;
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool ViewingsSpecified;
xmlAttribs.XmlRoot = rootAttrib;
namespace PropertyExchange
{
/// <summary>
/// Summary description for XmlNodeDeserializer.
/// </summary>
internal class XmlNodeDeserializer
{
static Hashtable serializerCache = new Hashtable(2);
static object serializerCacheLock = new object();
const string ns =
"www.charteris.com/namespaces/propertyexchange";
internal XmlNodeDeserializer() {
}
XmlReader localReader;
// If xmlReader is a validatingReader, need to use
// its reader
if (xmlReader is XmlValidatingReader) {
localReader = ((XmlValidatingReader)xmlReader).Reader;
}
else {
localReader = xmlReader;
}
string elementName = string.Empty;
Type objectType = null;
if (localReader.NodeType == XmlNodeType.Element) {
if (localReader.NamespaceURI == ns) {
switch (localReader.LocalName) {
case "Agent":
if (xmlSer == null) {
// As we are only deserializing a fragment, we need to
// add the XmlRootAttribute
// This is done by overriding the current attribute
XmlAttributes xmlAttribs = new XmlAttributes();
// Create the new XmlRootAttribute and set its
// name and namespace
XmlRootAttribute rootAttrib = new
XmlRootAttribute(elementName);
rootAttrib.Namespace = ns;
xmlAttribs.XmlRoot = rootAttrib;
The result of this is that the Deserialize method of the XmlNodeDeserializer will
deserialize the current element in the XML, and return it. It will also have moved the
current position in the XmlReader to the end of closing element tag. However, for this
to work, the XmlReader has to be at the start of the required element (in this case,
either an <Agent> or <Property> tag) when the Deserialize method is called.
Below is the code that is used to set up the XmlReader, move it to the correct position,
and then call the Deserialize method. In this case an XmlValidatingReader has
been used, but if schema validation is not required, an XmlTextReader can be used.
Note that if an XmlValidatingReader is used, only those nodes that are actually
read are validated against the schema. So in this case, if the XML is invalid somewhere
within the Properties node, the Agents will still get deserialized. This may or may not be
appropriate, depending on the application requirements.
const string ns = "www.charteris.com/namespaces/propertyexchange";
agent = (AgentType)ser.Deserialize(valReader);
1.6
1.4
1.2
1
Seconds
Full
0.8
Failed
0.6
0.4
0.2
0
Standard Item Deserialization Standard Item Deserialization
Deserialization Deserialization with with validation
validation
Working Set
18000000
17500000
17000000
Full
Failed
16500000
16000000
15500000
Standard Item Standard Item
Deserialization Deserialization Deserialization Deserialization
with validation with validation
Bytes
The above graphs show that deserializing each item just prior to processing is more
expensive in terms of execution time, by 32% for both an XmlTextReader and an
XmlValidatingReader. However, if processing fails early on, the execution times
6. CONCLUSIONS
If an application deserializes large XML documents, this can consume significant
amounts of memory. If this is done before any of the objects created are processed, it
may result in some of the objects never being used, as processing may be stopped
before they are used. As has been shown in this paper, significant gains can be made by
only deserializing objects as they are required. However, it should be remembered that
this will not always be appropriate, especially if it is expected that most of the time all
the entities will be processed.