|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Deserialize from SelectSingleNodeIs it possible to pull a single node (element) out of a complex XML
file, using SelectSingleNode(), and then deserialize that node to an object? Could someone please post, or point me to, a simple, but complete example? "Geoff" <geoffbis***@gmail.com> wrote in message news:db109b3f.0411171811.19f5ad33@posting.google.com... Yes, if your XML document looks like this, for example,> Is it possible to pull a single node (element) out of a complex XML > file, using SelectSingleNode(), and then deserialize that node to an > object? <MyDocument> <ComplexInfo> <DontCare SomeStatistic="55" /> </ComplexInfo> <MyObject> <Name>Geoff</Name> </MyObject> </MyDocument> and you have a class to deserialize that looks like this, public class MyObject { public string Name; } then you should have no problem selecting a single node, MyObject, from the more complex document and then wrapping that node in an XmlNodeReader to use for deserialization, like this, XmlSerializer serializer = new XmlSerializer( typeof( MyObject)); XmlDocument doc = new XmlDocument( ); doc.Load( "myDocument.xml"); XmlNode node = doc.SelectSingleNode( "//MyObject"); MyObject obj = serializer.Deserialize( new XmlNodeReader( node)) as MyObject; Derek Harmon Derek, thank you so much for the excellent response. You are a
gentleman and a scholar. You have confirmed for me that my approach should work, but I'm still having trouble, I think because of namespaces declared in the XML file. Can you expand your example a bit to account for a default namespace in the XML file? Or, can you tell me what might be wrong with my code, below? The "deserialize" statement gives me the following error: There is an error in the XML document. --> <FIELDED_ADDRESS xmlns='http://www.telcordia.com/IDN/ELMS6'> was not expected. "FIELDED_ADDRESS" is the name of the node I'm trying to select/deserialize. "http://www.telcordia.com/IDN/ELMS6" is a namespace declared in the XML file. My code looks like this: XmlDocument ResponseDocument = new XmlDocument(); ResponseDocument.Load @"C:\MyFile.xml"); NamespaceManager = new XmlNamespaceManager(ResponseDocument.NameTable); NamespaceManager.AddNamespace("p", "http://www.telcordia.com/IDN/ELMS6"); XPathQuery = @"//p:FIELDED_ADDRESS"; XmlNode AddressNode = ResponseDocument.SelectSingleNode(XPathQuery, NamespaceManager); if (AddressNode != null) { ALTERNATIVE_ADDRESSFIELDED_ADDRESS FieldedAddress; XmlNodeReader NodeReader = new XmlNodeReader(AddressNode); XmlSerializer Serializer = new XmlSerializer(typeof(ALTERNATIVE_ADDRESSFIELDED_ADDRESS), "http://www.telcordia.com/IDN/ELMS6"); FieldedAddress = Serializer.Deserialize(NodeReader) as ALTERNATIVE_ADDRESSFIELDED_ADDRESS; } My XML file looks like this: <?xml version="1.0" ?> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <Object Id="pp"> <ADDRESS_VALIDATION_OUTPUT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.telcordia.com/IDN/ELMS6" version="ELMS6_ADDRESS_VALIDATION_OUTPUT_v2-0" xsi:schemaLocation="http://www.telcordia.com/IDN/ELMS6 ADDRESS_VALIDATION_OUTPUT.xsd"> <COMMON_QUERY_RSP></COMMON_QUERY_RSP> <ALTERNATIVE_ADDRESS_INFORMATION_LIST> <ALTERNATIVE_ADDRESS_INFORMATION> <ALTERNATIVE_ADDRESS> <FIELDED_ADDRESS> <SANO>1445</SANO> <SATH>DR</SATH> <SASN>MONROE</SASN> <SASS>NE</SASS> <LD3>APT</LD3> <LV3>C-27</LV3> <CITY>ATLANTA</CITY> <STATE>GA</STATE> </FIELDED_ADDRESS> </ALTERNATIVE_ADDRESS> </ALTERNATIVE_ADDRESS_INFORMATION> </ALTERNATIVE_ADDRESS_INFORMATION_LIST> </ADDRESS_VALIDATION_OUTPUT> </Object> </Signature> OK. I got this working finally! Cool. Thank you.
The Serializer.Deserialize() method kept giving me "XXX was not expected." I thought it was talking about the namespace for XXX, but it was actually complaining about the entire element. Why?... Apparently because my class name didn't exactly match the element in the XML file. Unfortunately, my class name was generated from an XSD file for the XML file I'm working with. The class name has the form AAABBBCCC, where the actual element I'm interested in, CCC, is nested under elements AAA and BBB. I really don't want to change it, to match the element, because if the XSD changes in the future, I will use the xsd.exe tool to regenerate the classes, and any manual changes I've made will get blasted. Maybe there is an option for xsd.exe to generate class names which match the element names, or maybe there is a way to do the Deserialize() without the names matching. ??? I was able to use the XmlRoot attribute to map the class name to the
element name in the XML file, so at least now I won't have to actually change the xsd.exe generated classes themselves. Only issue now is I'll have to add the attribute any time the XSD file changes. Not such a big deal. Example below: [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.telcordia.com/IDN/ELMS6")] [XmlRoot (ElementName="FIELDED_ADDRESS")] public class ADDRESS_VALIDATION_OUTPUTALTERNATIVE_ADDRESS_INFORMATIONALTERNATIVE_ADDRESSFIELDED_ADDRESS Thanks Derek. Just curious if Deserializing the whole thing with
XmlSerializer to get the MyObject string and using that to deserialize the string xml would be faster or slower? Naturally you would need to define MyDocument in a class first. Does not XmlDocument deserializing the whole thing also just to find the MyObject tag? TIA Show quote "Derek Harmon" <loresa***@msn.com> wrote in message news:OHhEmuezEHA.824@TK2MSFTNGP11.phx.gbl... > "Geoff" <geoffbis***@gmail.com> wrote in message news:db109b3f.0411171811.19f5ad33@posting.google.com... > > Is it possible to pull a single node (element) out of a complex XML > > file, using SelectSingleNode(), and then deserialize that node to an > > object? > > Yes, if your XML document looks like this, for example, > > <MyDocument> > <ComplexInfo> > <DontCare SomeStatistic="55" /> > </ComplexInfo> > <MyObject> > <Name>Geoff</Name> > </MyObject> > </MyDocument> > > and you have a class to deserialize that looks like this, > > public class MyObject > { > public string Name; > } > > then you should have no problem selecting a single node, MyObject, > from the more complex document and then wrapping that node in an > XmlNodeReader to use for deserialization, like this, > > XmlSerializer serializer = new XmlSerializer( typeof( MyObject)); > XmlDocument doc = new XmlDocument( ); > doc.Load( "myDocument.xml"); > > XmlNode node = doc.SelectSingleNode( "//MyObject"); > MyObject obj = serializer.Deserialize( new XmlNodeReader( node)) as MyObject; > > > Derek Harmon > > |
|||||||||||||||||||||||