public class GoXmlReader : GoXmlReaderWriterBase
XmlDocument
or just an XmlReader
.public class GoXmlReader : GoXmlReaderWriterBase
Depending on which overload of Consume
is called, you can either traverse an XmlDocument
that you supply, you can load an XmlDocument
from a Stream (if UseDOM is true), or you can just handle the elements as they are read in by an XmlReader
from a Stream (if UseDOM is false). The processing of XML elements is basically done in a single pass, but there is built-in functionality for a second pass to fix up references in the objects that were constructed.
You must provide type-specific customizations by supplying instances of IGoXmlTransformer. Each transformer is associated with a Type
(IGoXmlTransformer.TransformerType) and an ElementName
string (IGoXmlTransformer.ElementName).
By default there are no transformers registered for this reader, so this reader is unable to actually do anything with the XML elements it sees. You will need to call GoXmlReaderWriterBase.AddTransformer for each class of object for which you want to consume XML. These calls to GoXmlReaderWriterBase.AddTransformer are sometimes done in an override of GoXmlReaderWriterBase.RegisterTransformers, but you probably do not need to define a class inheriting from GoXmlReader.
ConsumeRootBody does the bulk of the work to traverse the elements in the XmlDocument
root, or (if UseDOM is false) just to read elements from the XmlReader. As this reader processes each element, it calls ConsumeObject. ConsumeObject calls InvokeAllocate to actually allocate an object, and if an object is allocated, calls InvokeConsumeAttributes InvokeConsumeBody, and InvokeConsumeObjectFinish to actually reconstruct the rest of the object.
Although most of the information that needs to be reconstructed will be held in attributes of the element representing an object, there will sometimes be references to other objects. If you can be sure that the references will be to objects that have already been read, you can call MakeShared to remember an object by a key string, and you can call FindShared to recover that object by using the same key.
However, if the reference is to something that might not yet have been read and constructed, you can make use of the delayed-references mechanism that this reader offers. You can just call AddDelayedRef to remember the referring object, the property or other identifying string of the reference in this referring object, and the reference string to the referred-to object. This reference string is the same as the key used to identify shared objects.
Then the ProcessDelayedObjects method, called as a "second pass" after all of the elements in the XML root have been read, iterates over all of those delayed references, calls FindShared to resolve the reference, and then calls InvokeUpdateReference so that the transformer gets a chance to fix up the reference.
The various Invoke...
methods do the actual lookup for a transformer and invoke the respective method on the first transformer found.
public void LoadSimpleXml(String path) { myView.Document.Clear(); // assume we're replacing current document contents GoXmlReader xr = new GoXmlReader(); // tell the reader how to handle two kinds of elements xr.AddTransformer(new SimpleXmlTransformBasicNode()); xr.AddTransformer(new SimpleXmlTransformLink()); xr.RootObject = myView.Document; using (StreamReader sr = new StreamReader(path)) { xr.Consume(sr); } }