Link to home
Start Free TrialLog in
Avatar of countrymeister
countrymeister

asked on

How to insert a namespace into an xml doument

I have an xml document that needs to have a particular namespace before it can be deserialized

I need this namespace added to the root element Records
xmlns="http://XYZCompany/XYZ.xsd"

Can this be done other than doing string replace of "<Records" to "<Records xmlns="http://XYZCompany/XYZ.xsd" "

<Records>
    <Result>GOOD</Result>
    <Status>0</Status>
    <Data>
        <UserName>TEST</UserName>
        <UploadTimeStamp>2010-04-07</UploadTimeStamp>
        <Type>xml</Type>        
    </Data>
</Records>

Need to look like this with the namespace
<Records xmlns="http://XYZCompany/XYZ.xsd">
    <Result>GOOD</Result>
    <Status>0</Status>
    <Data>
        <UserName>TEST</UserName>
        <UploadTimeStamp>2010-04-07</UploadTimeStamp>
        <Type>xml</Type>        
    </Data>
</Records>

Open in new window

Avatar of _Katka_
_Katka_
Flag of Czechia image

Hi, yes you have to save it with the node.. for example in XDocument approach:

XElement myElement = new XElement(xmlNamespace + elementName);

where xmlNamespace is XNamespace (your http://XYZCompany/XYZ.xsd)

It has to be on all the nodes in the tree, but it will appear to be only in the root.
So you basically need to add it to every node (not attribute) while adding programmatically.

As it appears in C# code:

<Records xmlns="http://XYZCompany/XYZ.xsd">
    <Result xmlns="http://XYZCompany/XYZ.xsd">GOOD</Result>
    <Status xmlns="http://XYZCompany/XYZ.xsd">0</Status>
    <Data xmlns="http://XYZCompany/XYZ.xsd">
        <UserName xmlns="http://XYZCompany/XYZ.xsd">TEST</UserName>
        <UploadTimeStamp xmlns="http://XYZCompany/XYZ.xsd">2010-04-07</UploadTimeStamp>
        <Type xmlns="http://XYZCompany/XYZ.xsd">xml</Type>        
    </Data>
</Records>

This will look like this when saved:

<Records xmlns="http://XYZCompany/XYZ.xsd">
    <Result>GOOD</Result>
    <Status>0</Status>
    <Data>
        <UserName>TEST</UserName>
        <UploadTimeStamp>2010-04-07</UploadTimeStamp>
        <Type>xml</Type>        
    </Data>
</Records>

regards,
Kate


Avatar of countrymeister
countrymeister

ASKER

Katka,

I have an xmldocument object  xDoc in my code, whose InnerXML has the xml that looks like this

<Records>
    <Result>GOOD</Result>
    <Status>0</Status>
    <Data>
        <UserName>TEST</UserName>
        <UploadTimeStamp>2010-04-07</UploadTimeStamp>
        <Type>xml</Type>        
    </Data>
</Records>

here is the code
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(somexmlstring)

How do I modify xDoc to add the namespace, I did not follow your example

Ok, it's kind of hard to explain.

You need to go thru all the nodes in the document and the attribute to them:

eachElement.SetAttribute("xmlns", "http://XYZCompany/XYZ.xsd");

If you'd added only to the root, those children would have a different one.

You can go thru the sub-nodes like this:

XmlNode root = xDoc.DocumentElement;
IEnumerator nodes = root.GetEnumerator();
XmlNode node;

while (nodes.MoveNext())
{    
   node = (XmlNode) nodes.Current;
   node.SetAttribute("xmlns", "http://XYZCompany/XYZ.xsd");
}

Remember you have to do it recursively, for all the nodes.

regards,
Kate
I'd personally use XDocument instead like this:

XDocument xDoc = XDocument.Parse(someXmlString);
XNamespace xNamespace = "http://XYZCompany/XYZ.xsd";

foreach (XElement element in doc.Descendants())
{
    element.SetAttributeValue("xmlns", xNamespace.NamespaceName);
}

This should do all the work much easier. It sound confusing, but that is because XML is confusing on namespaces.

regards,
Kate
_Katka_:

Ge the following errors on your code sample
System.Xml.XmlNode' does not contain a definition for 'SetAttribute
Using the generic type 'System.Collections.Generic.IEnumerator<T>' requires '1' type arguments      
Weird it's taken directly from MSDN.
I guess all those XNode should be XElement.

regards,
Kate
XmlNode => XmlElement
Katka

Not sure if this class objects or methods exist in .NET - Xnamespace XmlDocument..Descendants())

here is your code that you provided
XNamespace xNamespace = "http://XYZCompany/XYZ.xsd";
foreach (XElement element in doc.Descendants())
{
    element.SetAttributeValue("xmlns", xNamespace.NamespaceName);
}
ASKER CERTIFIED SOLUTION
Avatar of _Katka_
_Katka_
Flag of Czechia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here goes the example directly from Microsoft to do this whole change:

http://msdn.microsoft.com/en-us/library/bb943914.aspx

regards,
Kate
Katka,

Unfortunately I am using VS 2005, due to some restrictions in my project and 2.0 does not have linq.
Is there anyway this can be achived without Linq
Thanks for all the help
Ok, I finally get out of work, so I can put together some sample.

XmlDocument document = new XmlDocument();
document.Load(@"C:\Test.xml");
document.DocumentElement.SetAttribute("xmlns", "http://XYZCompany/XYZ.xsd");
document.Save(@"C:\Output.xml");

This should do what you want.

regards,
Kate
Katka, thanks for your help.