Change case in First node in XmlDocument - c#

I have this XML:
<Feedback>
<Officer>Officer</Officer>
<Answers>My text</Answers>
<Date>20190917</Date>
</Feedback>
I want XML to look like this: (Lowercase first letter in main tag)
<feedback>
<Officer>Officer</Officer>
<Answers>My text</Answers>
<Date>20190917</Date>
</feedback>
How to do it using XMLDocument? I can't access this item

If using XmlDocument is not a hard requirement you can do it with linq fairly easily.
You can create a new XML document with the root node named how you want it then loop through the child nodes of the original and add them to your new XML object.
A simple example:
XDocument xDocument = XDocument.Parse("<Feedback><Officer>Officer</Officer><Answers>My text</Answers><Date>20190917</Date></Feedback>");
XDocument newDoc = new XDocument();
XElement rootElement = new XElement("feedback");
newDoc.Add(rootElement);
foreach (var node in xDocument.Root.Elements())
{
newDoc.Root.Add(node);
}
Console.WriteLine(newDoc);
Console.ReadLine();
However here is an example using XmlDocument if you really need to use that:
XmlDocument oldDoc = new XmlDocument();
XmlDocument newXmlDoc = new XmlDocument();
oldDoc.LoadXml("<Feedback><Officer>Officer</Officer><Answers>My text</Answers><Date>20190917</Date></Feedback>");
XmlElement newRoot = newXmlDoc.CreateElement("feedback");
newXmlDoc.AppendChild(newRoot);
XmlNode root = newXmlDoc.DocumentElement;
foreach (XmlNode node in oldDoc.FirstChild.ChildNodes)
{
XmlElement elem = newXmlDoc.CreateElement(node.Name);
elem.InnerText = node.InnerText;
//Add the node to the document.
root.AppendChild(elem);
}
XmlTextWriter writer = new XmlTextWriter(Console.Out);
writer.Formatting = Formatting.Indented;
newXmlDoc.WriteTo(writer);
writer.Flush();
Console.WriteLine();
Console.ReadLine();

In this case, you can change the name directly:
var XML = ""; // Your XML in string
var tempDoc = new XmlDocument();
tempDoc.LoadXml(XML);
tempDoc.InnerXml = tempDoc.InnerXml.Replace("Feedback>", "feedback>");
XML = tempDoc.OuterXml;
This is a simple way to change the name
Do not use in other situations because various errors may arise, e.g another element may end in the same name

Related

Insert a string in a particular position into an other string

I am work on some innerxml of an XML document.
I have to concat several parts.
I have this:
<TRANFSERT><GOOD></GOOD></TRANSFERT>
I want to insert another part, <GOOD></GOOD>, before </TRANSFERT>.
I tried this:
int pos = xmldoc.indexOf("</GOOD>");
StringBuilder sb = new StringBuilder(xmlFinal);
sb.Append(xmlModifiee,pos,xmlModifiee.length);
xmlFinal = sb.ToString();
But it doesn't work.
How can I add a small part of XML in other XML?
You shouldn't interact with XML like with ordinary string.
Use provided System.Xml.XmlDocument or System.Xml.Linq.XDocument classes:
Ordinary XmlDocument single node selection and appending new element to it:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("YourFile.xml");
XmlNode goodNode = xmlDocument.SelectSingleNode("TRANSFERT/GOOD");
XmlNode nodeToInsert = xmlDocument.CreateElement("INSERTEDNODE");
goodNode.AppendChild(nodeToInsert);
Ordinary XmlDocument iterating by nodes to find necessary (be aware for many-childed nodes) and add new child node to it:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("YourFile.xml");
foreach (XmlNode rootNode in xmlDocument.ChildNodes)
{
if (rootNode.Name == "TRANSFERT")
{
foreach (XmlNode childNode in rootNode.ChildNodes)
{
if (childNode.Name == "GOOD")
{
XmlNode nodeToInsert = xmlDocument.CreateElement("INSERTEDNODE");
childNode.AppendChild(nodeToInsert);
}
}
}
}
Linq to XML variant:
XDocument xDoc = XDocument.Load("YourFIle.xml");
XElement rootElement = xDoc.Element("TRANSFERT");
XElement goodElement = rootElement.Element("GOOD");
goodElement.Add(new XElement("INSERTEDNODE"));
Simplified Linq to XML variant:
XDocument.Load("YourFIle.xml").Element("TRANSFERT").Element("GOOD").Add(new XElement("INSERTEDNODE"));
EDITED: answering the question, example was rewrited from changing InnerText values to Append/Add new child element to GOOD node.
StringBuilder.Append can only be used to add something to the end of the string. To add something inside the string, use StringBuilder.Insert like this:
sb.Insert(pos, xmlModifiee);

get grandson text using xml document in c#

I'm using XmlDocument in C# and I would like to know how to get grandson data of the root?
<tRoot>
<One>
<a>15</a>
<b>11</b>
<c>1</c>
<d>11.35</d>
<e>0</e>
<f>289</f>
</One>
<Two>
<a>0</a>
<b>11</b>
<c>1</c>
<d>0.28</d>
<e>0</e>
<f>464</f>
</Two>
</tRoot>
and I want the ability to get a of One and also a of Two
I tried:
var doc = new XmlDocument();
doc.Load(Consts.FileConst);
var docXml = doc["One"];
if (docXml != null)
{
float valFromXml = float.Parse(docXml["a"].InnerText);
}
The issue is that docXml is null
Any assitance?
As suggested above, XDocument would be a better alternative. If, however, you still want to use XmlDocument, you can iterate through the children using
var doc = new XmlDocument();
doc.Load(Consts.FileConst);
foreach(XmlNode xmlNode in doc.DocumentElement.ChildNodes) {
//access a/b/c/d/e using:
xmlNode.ChildNodes[0].InnerText; //for a
xmlNode.ChildNodes[1].InnerText; //for b
}
Try this:
XmlDocument d = new XmlDocument();
d.LoadXml("<tRoot><One><a>15</a><b>11</b><c>1</c><d>11.35</d><e>0</e><f>289</f></One><Two><a>0</a><b>11</b><c>1</c><d>0.28</d><e>0</e><f>464</f></Two></tRoot>");
XmlNodeList itemNodes = d.SelectNodes("//*/a");

Adding info to a xml file

I have a XML file which contains about 850 XML nodes. Like this:
<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
</NameValueItem>
........ 849 more
And I want to add a new Childnode inside each and every Node. So I end up like this:
<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
<Description>TestDescription</Description>
</NameValueItem>
........ 849 more
I've tried the following:
XmlDocument doc = new XmlDocument();
doc.Load(xmlPath);
XmlNodeList nodes = doc.GetElementsByTagName("NameValueItem");
Which gives me all of the nodes, but from here am stuck(guess I need to iterate over all of the nodes and append to each and every) Any examples?
You need something along the lines of this example below. On each of your nodes, you need to create a new element to add to it. I assume you will be getting different values for the InnerText property, but I just used your example.
foreach (var rootNode in nodes)
{
XmlElement element = doc.CreateElement("Description");
element.InnerText = "TestDescription";
root.AppendChild(element);
}
You should just be able to use a foreach loop over your XmlNodeList and insert the node into each XmlNode:
foreach(XmlNode node in nodes)
{
node.AppendChild(new XmlNode()
{
Name = "Description",
Value = [value to insert]
});
}
This can also be done with XDocument using LINQ to XML as such:
XDocument doc = XDocument.Load(xmlDoc);
var updated = doc.Elements("NameValueItem").Select(n => n.Add(new XElement() { Name = "Description", Value = [newvalue]}));
doc.ReplaceWith(updated);
If you don't want to parse XML using proper classes (i.e. XDocument), you can use Regex to find a place to insert your tag and insert it:
string s = #"<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
</NameValueItem>";
string newTag = "<Description>TestDescription</Description>";
string result = Regex.Replace(s, #"(?<=</Code>)", Environment.NewLine + newTag);
but the best solution is Linq2XML (it's much better, than simple XmlDocument, that is deprecated at now).
string s = #"<root>
<NameValueItem>
<Text>Test</Text>
<Code>Test</Code>
</NameValueItem>
<NameValueItem>
<Text>Test2</Text>
<Code>Test2</Code>
</NameValueItem>
</root>";
var doc = XDocument.Load(new StringReader(s));
var elms = doc.Descendants("NameValueItem");
foreach (var element in elms)
{
element.Add(new XElement("Description", "TestDescription"));
}
var text = new StringWriter();
doc.Save(text);
Console.WriteLine(text);

Read a XML (from a string) and get some fields - Problems reading XML

I have this XML (stored in a C# string called myXML)
<?xml version="1.0" encoding="utf-16"?>
<myDataz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<listS>
<sog>
<field1>123</field1>
<field2>a</field2>
<field3>b</field3>
</sog>
<sog>
<field1>456</field1>
<field2>c</field2>
<field3>d</field3>
</sog>
</listS>
</myDataz>
and I'd like to browse all <sog> elements. For each of them, I'd like to print the child <field1>.
So this is my code :
XmlDocument xmlDoc = new XmlDocument();
string myXML = "<?xml version=\"1.0\" encoding=\"utf-16\"?><myDataz xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><listS><sog><field1>123</field1><field2>a</field2><field3>b</field3></sog><sog><field1>456</field1><field2>c</field2><field3>d</field3></sog></listS></myDataz>"
xmlDoc.Load(myXML);
XmlNodeList parentNode = xmlDoc.GetElementsByTagName("listS");
foreach (XmlNode childrenNode in parentNode)
{
HttpContext.Current.Response.Write(childrenNode.SelectSingleNode("//field1").Value);
}
but seems I can't read a string as XML? I get System.ArgumentException
You should use LoadXml method, not Load:
xmlDoc.LoadXml(myXML);
Load method is trying to load xml from a file and LoadXml from a string. You could also use XPath:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
string xpath = "myDataz/listS/sog";
var nodes = xmlDoc.SelectNodes(xpath);
foreach (XmlNode childrenNode in nodes)
{
HttpContext.Current.Response.Write(childrenNode.SelectSingleNode("//field1").Value);
}
Use Linq-XML,
XDocument doc = XDocument.Load(file);
var result = from ele in doc.Descendants("sog")
select new
{
field1 = (string)ele.Element("field1")
};
foreach (var t in result)
{
HttpContext.Current.Response.Write(t.field1);
}
OR : Get the node list of <sog> tag.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(myXML);
XmlNodeList parentNode = xmlDoc.GetElementsByTagName("sog");
foreach (XmlNode childrenNode in parentNode)
{
HttpContext.Current.Response.Write(childrenNode.SelectSingleNode("field1").InnerText);
}
The other answers are several years old (and do not work for Windows Phone 8.1) so I figured I'd drop in another option. I used this to parse an RSS response for a Windows Phone app:
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(xml_string);
Or use the XmlSerializer class.
XmlSerializer xs = new XmlSerializer(objectType);
obj = xs.Deserialize(new StringReader(yourXmlString));
I used the System.Xml.Linq.XElement for the purpose. Just check code below for reading the value of first child node of the xml(not the root node).
string textXml = "<xmlroot><firstchild>value of first child</firstchild>........</xmlroot>";
XElement xmlroot = XElement.Parse(textXml);
string firstNodeContent = ((System.Xml.Linq.XElement)(xmlroot.FirstNode)).Value;

Change XML root element name

I have XML stored in string variable:
<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>
Here I want to change XML tag <ItemMasterList> to <Masterlist>. How can I do this?
System.Xml.XmlDocument and the associated classes in that same namespace will prove invaluable to you here.
XmlDocument doc = new XmlDocument();
doc.LoadXml(yourString);
XmlDocument docNew = new XmlDocument();
XmlElement newRoot = docNew.CreateElement("MasterList");
docNew.AppendChild(newRoot);
newRoot.InnerXml = doc.DocumentElement.InnerXml;
String xml = docNew.OuterXml;
I know i am a bit late, but just have to add this answer as no one seems to know about this.
XDocument doc = XDocument.Parse("<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>");
doc.Root.Name = "MasterList";
Which returns the following:
<MasterList>
<ItemMaster>
<fpartno>xxx</fpartno>
<frev>000</frev>
<fac>Default</fac>
</ItemMaster>
</MasterList>
You can use LINQ to XML to parse the XML string, create a new root and add the child elements and attributes of the original root to the new root:
XDocument doc = XDocument.Parse("<ItemMasterList>...</ItemMasterList>");
XDocument result = new XDocument(
new XElement("Masterlist", doc.Root.Attributes(), doc.Root.Nodes()));
Using the XmlDocument way, you can do this as follows (and keep the tree intact):
XmlDocument oldDoc = new XmlDocument();
oldDoc.LoadXml("<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>");
XmlNode node = oldDoc.SelectSingleNode("ItemMasterList");
XmlDocument newDoc = new XmlDocument();
XmlElement ele = newDoc.CreateElement("MasterList");
ele.InnerXml = node.InnerXml;
If you now use ele.OuterXml is will return: (you you just need the string, otherwise use XmlDocument.AppendChild(ele) and you will be able to use the XmlDocument object some more)
<MasterList>
<ItemMaster>
<fpartno>xxx</fpartno>
<frev>000</frev>
<fac>Default</fac>
</ItemMaster>
</MasterList>
As pointed by Will A, we can do it that way but for case where InnerXml equals the OuterXml the following solution will work out:
// Create a new Xml doc object with root node as "NewRootNode" and
// copy the inner content from old doc object using the LastChild.
XmlDocument docNew = new XmlDocument();
XmlElement newRoot = docNew.CreateElement("NewRootNode");
docNew.AppendChild(newRoot);
// The below line solves the InnerXml equals the OuterXml Problem
newRoot.InnerXml = oldDoc.LastChild.InnerXml;
string xmlText = docNew.OuterXml;

Categories

Resources