Appending XML to existing XmlDocument

J

Jesper Stocholm

I have a database class that maintains data about customers i my system.
The basic XML for this looks like:

<Chunk>
<Vendor>
<Database/>
</Vendor>
</Chunk>

When a user is to be registrered in the system, XML like this is created
in a seperate XML-class (Xml):

<User>
<UserName>stocholm</UserName>
<NumberOfItemsBought>0</NumberOfItemsBought>
<SignOfLastImage>A31A20AB338B6F2FD772ECFA0</SignOfLastImage>
<n>DB1A46496C83DFFC0CA2BA91585AA25E90195B77DB5997DA3D</n>
<e>AAB7E2A0F</e>
</User>

This piece of XML should be appended as a child of the element "User"
such that the XML will look like this:

<Chunk>
<Vendor>
<Database>
<User>
<UserName>stocholm</UserName>
<NumberOfItemsBought>0</NumberOfItemsBought>
<SignOfLastImage>A31A20AB338B6F2FE</SignOfLastImage>
<n>B1A46496C83DFFC0CA2BA91585AA25E90195B77DB5997</n>
<e>AAB7E2A0F</e>
</User>
</Database>
</Vendor>
</Chunk>

But how do I insert the new piece of XML via DOM? My base xml is loaded
in an XmlDocument object, and the new XML is created like this in my Xml
class:

public static XmlNode CreateXmlForDatabase(
string userName,string n,string e,string signOfLastImage
)
{
XmlDocument xDoc = new XmlDocument();
XmlNode node = xDoc.CreateNode(XmlNodeType.Element,"User",null);
XmlElement elem = xDoc.CreateElement(null,"UserName",null);
elem.InnerText = userName;
node.AppendChild(elem);
elem = xDoc.CreateElement(null,"NumberOfItemsBought",null);
elem.InnerText = "0";
node.AppendChild(elem);
elem = xDoc.CreateElement(null,"SignOfLastImage",null);
elem.InnerText = signOfLastImage;
node.AppendChild(elem);
elem = xDoc.CreateElement(null,"n",null);
elem.InnerText = n;
node.AppendChild(elem);
elem = xDoc.CreateElement(null,"e",null);
elem.InnerText = e;
node.AppendChild(elem);
return node;
}

If I try with this in my database class:

XmlNode node = Xml.CreateXmlForDatabase(username,n,e,SignOfLastImage);
XmlNode newUser = _xDoc.SelectSingleNode("/Chunk/Vendor/Database");
newUser.AppendChild(node);

I get the error

"The node to be inserted is from a different document context."

Why is that?

The base XML in my database class is initialized as

static XmlDocument _xDoc = new XmlDocument();
_xDoc.LoadXml("<Chunk><Vendor><Database/></Vendor></Chunk>");

I hope you can help me out on this one,

Thanks, :blush:)
 
J

Jon Skeet [C# MVP]

If I try with this in my database class:

XmlNode node = Xml.CreateXmlForDatabase(username,n,e,SignOfLastImage);
XmlNode newUser = _xDoc.SelectSingleNode("/Chunk/Vendor/Database");
newUser.AppendChild(node);

I get the error

"The node to be inserted is from a different document context."

The easiest way to get away from this is to pass the XmlDocument you'll
be including it in to CreateXmlForDatabase rather than creating an
XmlDocument within the method. However, you could also use the
XmlDocument.ImportNode method - see the details within MSDN for more
information.
 
J

Jesper Stocholm

Jon Skeet [C# MVP] wrote :

Hi Jon, thanks for your prompt reply,
The easiest way to get away from this is to pass the XmlDocument you'll
be including it in to CreateXmlForDatabase rather than creating an
XmlDocument within the method. However, you could also use the
XmlDocument.ImportNode method - see the details within MSDN for more
information.

I have tried with ImortNode-method, and it nicely imports the data from
the new XmlDocument ... only it is at the wrong place.

My code is this:

XmlDocument newUser = new XmlDocument();
newUser = Xml.CreateXmlForDatabase(username,n,e,SignOfLastImage);
XmlNode nodeUser = _xDoc.ImportNode(newUser.SelectSingleNode
("User"),true);
_xDoc.DocumentElement.AppendChild(nodeUser);

The Xml should look like

<Chunk>
<Vendor>
<Database>
<User>
<UserName>stocholm</UserName>
...
</User>
</Database>
</Vendor>
</Chunk>

But it is now

<Chunk>
<Vendor>
<Database/>
</Vendor>
<User>
<UserName>stocholm</UserName>
...
</User>
</Chunk>

How can I make it import the XML-chunk as a child of the Database-
element?
 
J

Jon Skeet [C# MVP]

Jesper Stocholm said:
My code is this:

XmlDocument newUser = new XmlDocument();
newUser = Xml.CreateXmlForDatabase(username,n,e,SignOfLastImage);
XmlNode nodeUser = _xDoc.ImportNode(newUser.SelectSingleNode
("User"),true);
_xDoc.DocumentElement.AppendChild(nodeUser);

How can I make it import the XML-chunk as a child of the Database-
element?

Just append it as a child of the appropriate element. You're calling
DocumentElement.AppendChild, so it's appending it to the
DocumentElement (which is <Chunk>). There are any number of ways of
getting to the right node (e.g. XPath, straight DOM manipulation etc).
Once you've got the right node, just call AppendChild on that, instead
of the DocumentElement.
 
J

Jesper Stocholm

Jesper Stocholm wrote :
Jon Skeet [C# MVP] wrote :
The easiest way to get away from this is to pass the XmlDocument
you'll be including it in to CreateXmlForDatabase rather than
creating an XmlDocument within the method. However, you could also
use the XmlDocument.ImportNode method - see the details within MSDN
for more information.

I have tried with ImortNode-method, and it nicely imports the data
from the new XmlDocument ... only it is at the wrong place.

How can I make it import the XML-chunk as a child of the Database-
element?

I found the answer myself. This code does the trick:

XmlDocument newUser = new XmlDocument();
newUser = Xml.CreateXmlForDatabase(username,n,e,SignOfLastImage);
XmlNode nodeDatabase = _xDoc.SelectSingleNode("/Chunk/Vendor/Database");
XmlNode nodeUser = _xDoc.ImportNode(newUser.SelectSingleNode("User"),true);
nodeDatabase.AppendChild(nodeUser);

:blush:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top