views:

773

answers:

4

I'm trying to access UPS tracking info and, as per their example, I need to build a request like so:

<?xml version="1.0" ?>
<AccessRequest xml:lang='en-US'>
   <AccessLicenseNumber>YOURACCESSLICENSENUMBER</AccessLicenseNumber>
   <UserId>YOURUSERID</UserId>
   <Password>YOURPASSWORD</Password>
</AccessRequest>
<?xml version="1.0" ?>
<TrackRequest>
   <Request>
     <TransactionReference>
         <CustomerContext>guidlikesubstance</CustomerContext>
     </TransactionReference>
     <RequestAction>Track</RequestAction>
   </Request>
   <TrackingNumber>1Z9999999999999999</TrackingNumber>
</TrackRequest>

I'm having a problem creating this with 1 XmlDocument in C#. When I try to add the second: <?xml version="1.0" ?> or the <TrackRequest> it throws an error:

System.InvalidOperationException: This document already has a 'DocumentElement' node.

I'm guessing this is because a standard XmlDocument would only have 1 root node. Any ideas?

Heres my code so far:

XmlDocument xmlDoc = new XmlDocument();
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
XmlElement rootNode = xmlDoc.CreateElement("AccessRequest");
rootNode.SetAttribute("xml:lang", "en-US");
xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
xmlDoc.AppendChild(rootNode);

XmlElement licenseNode = xmlDoc.CreateElement("AccessLicenseNumber");
XmlElement userIDNode = xmlDoc.CreateElement("UserId");
XmlElement passwordNode = xmlDoc.CreateElement("Password");

XmlText licenseText = xmlDoc.CreateTextNode("mylicense");
XmlText userIDText = xmlDoc.CreateTextNode("myusername");
XmlText passwordText = xmlDoc.CreateTextNode("mypassword");

rootNode.AppendChild(licenseNode);
rootNode.AppendChild(userIDNode);
rootNode.AppendChild(passwordNode);

licenseNode.AppendChild(licenseText);
userIDNode.AppendChild(userIDText);
passwordNode.AppendChild(passwordText);

XmlElement rootNode2 = xmlDoc.CreateElement("TrackRequest");
xmlDoc.AppendChild(rootNode2);
A: 

Build two separate XML documents and concatenate their string representation.

VVS
+7  A: 

An XML document can only ever have one root node. Otherwise it's not well formed. You will need to create 2 xml documents and join them together if you need to send both at once.

Russell Troywest
+2  A: 

Its throwing an exception because you are trying to create invalid xml. XmlDocument will only generate well formed xml.

You could do it using an XMLWriter and setting XmlWriterSettings.ConformanceLevel to Fragment or you could create two XmlDocuments and write them out into the same stream.

pjbelf
A: 

It looks like your node structure always be the same. (I don't see any conditional logic.) If the structure is constant you could define an XML template string. Load that string into an XML Document & do a SelectNode to populate individual nodes.

That may be simpler/cleaner than programatically creating the root, elements & nodes.

Mark Maslar