• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 436
  • Last Modified:

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

0
countrymeister
Asked:
countrymeister
  • 8
  • 5
1 Solution
 
_Katka_Commented:
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


0
 
countrymeisterAuthor Commented:
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

0
 
_Katka_Commented:
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
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
_Katka_Commented:
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
0
 
countrymeisterAuthor Commented:
_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      
0
 
_Katka_Commented:
Weird it's taken directly from MSDN.
I guess all those XNode should be XElement.

regards,
Kate
0
 
_Katka_Commented:
XmlNode => XmlElement
0
 
countrymeisterAuthor Commented:
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);
}
0
 
_Katka_Commented:
Hi, sure it does, I'm using it everywhere.. you just need to reference the System.Xml.Linq..

http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx
http://msdn.microsoft.com/en-us/library/system.xml.linq.xnamespace.aspx

regards,
Kate
0
 
_Katka_Commented:
Here goes the example directly from Microsoft to do this whole change:

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

regards,
Kate
0
 
countrymeisterAuthor Commented:
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
0
 
_Katka_Commented:
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
0
 
countrymeisterAuthor Commented:
Katka, thanks for your help.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 8
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now