yongsing
asked on
Adding an Attribute to an XML Element
I have an XML document, and I would like to add an attribute to a particular element. For example, in the following XML (not fully shown), there is an element called s:any:
...
<s:element name="TypedDataSet">
<s:complexType>
<s:sequence>
<s:any />
</s:sequence>
</s:complexType>
</s:element>
...
I want to add an attribute namespace="http://www.tempuri.org/TypedDataSet.xsd" to all elements with s:any name. In the above example, the result will be like:
...
<s:element name="TypedDataSet">
<s:complexType>
<s:sequence>
<s:any namespace="http://www.tempuri.org/TypedDataSet.xsd"/>
</s:sequence>
</s:complexType>
</s:element>
...
I would appreciate a full example showing how to read the XML document, adding in the attribute, and saving the document.
Thanks in advance.
...
<s:element name="TypedDataSet">
<s:complexType>
<s:sequence>
<s:any />
</s:sequence>
</s:complexType>
</s:element>
...
I want to add an attribute namespace="http://www.tempuri.org/TypedDataSet.xsd" to all elements with s:any name. In the above example, the result will be like:
...
<s:element name="TypedDataSet">
<s:complexType>
<s:sequence>
<s:any namespace="http://www.tempuri.org/TypedDataSet.xsd"/>
</s:sequence>
</s:complexType>
</s:element>
...
I would appreciate a full example showing how to read the XML document, adding in the attribute, and saving the document.
Thanks in advance.
Incidentally, I was perhaps a little terse on the XPath statement; you may be better with a precise path such as:
XmlElement element = (XmlElement) document.SelectSingleNode( "/element/ complexTyp e/sequence /any");
(Which as I stated you may need to qualify with the "s" namespace prefix")
Keith.
XmlElement element = (XmlElement) document.SelectSingleNode(
(Which as I stated you may need to qualify with the "s" namespace prefix")
Keith.
ASKER
Thanks, it works.
If the "any" element is qualified with some other unknown namespace, can I still add the attribute? For example, it could be qualified with "xxx" or even not qualified with any namespace. In other words, I want to add the attribute to all elements with the name "any" regardless of what namespace it is qualified with.
If the "any" element is qualified with some other unknown namespace, can I still add the attribute? For example, it could be qualified with "xxx" or even not qualified with any namespace. In other words, I want to add the attribute to all elements with the name "any" regardless of what namespace it is qualified with.
If you can get a reference to the node without knowing the namespace (which is perfectly possible) then yes. The implementation of XPath I've used most does insist that you qualify XPath expressions with namespaces, which makes sense, since they are effectively differently named nodes, in the same way that two classes in C# with the same name but living in different namespaces are distinct entities in their own right.
You could write a similar program however not using XPath that recursed down all of the nodes in the tree looking for nodes with the name "Any" and performing exactly the same operation as above on each of these elements.
You could write a similar program however not using XPath that recursed down all of the nodes in the tree looking for nodes with the name "Any" and performing exactly the same operation as above on each of these elements.
ASKER
Hi, sorry for not getting back earlier. For your suggestion of recursing down all of the nodes in the tree looking for nodes with the name "any", can you provide an example? Thanks!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Keith, thanks.
If I add the following to the XML, it won't work:
string testXmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<Test><Node2><Keith></Kei th></Node2 ></Test>";
There will be an exception on this line:
XmlElement rootNode = (XmlElement) document.ChildNodes.Item(0 );
It can be fixed by changing the index from 0 to 1:
XmlElement rootNode = (XmlElement) document.ChildNodes.Item(1 );
How can I know that there is a <?xml ... ?> in front?
If I add the following to the XML, it won't work:
string testXmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<Test><Node2><Keith></Kei
There will be an exception on this line:
XmlElement rootNode = (XmlElement) document.ChildNodes.Item(0
It can be fixed by changing the index from 0 to 1:
XmlElement rootNode = (XmlElement) document.ChildNodes.Item(1
How can I know that there is a <?xml ... ?> in front?
ASKER
I just found out that you need to check whether the type is XmlElement:
for (int i = 0; i < document.ChildNodes.Count; i++)
{
if (document.ChildNodes.Item( i) is XmlElement)
{
XmlElement xmlElement = (XmlElement)document.Child Nodes.Item (i);
addAttributeToNodeWithName (xmlElemen t, "any");
}
}
I'll get back to you again... :)
for (int i = 0; i < document.ChildNodes.Count;
{
if (document.ChildNodes.Item(
{
XmlElement xmlElement = (XmlElement)document.Child
addAttributeToNodeWithName
}
}
I'll get back to you again... :)
ASKER
Thanks Keith, I finally got what I want!
You need to include:
using System.Xml;
using System.IO;
// I had to remove the namespace prefix; you've only supplied part of the XML document (it won't parse without it)
string s = "<element name='TypedDataSet'><compl
XmlDocument document = new XmlDocument();
document.LoadXml(s);
// Alternative, to read from a file on disk rather from the string above
// document.Load(new XmlTextReader("file://c:\\
// This may have to change to "//s:any" in your document
XmlElement element = (XmlElement) document.SelectSingleNode(
element.SetAttribute("name
// Write the output to a file on disk
StreamWriter writer = new StreamWriter("c:\\testoutp
writer.Write(document.Inne
writer.Close();
Hope that helps.