How to read XML child node element attributes in each iteration c#? - c#

<?xml version="1.0" encoding="utf-8" ?>
<Checkplan>
<masters>
<sections>
<characteristics>
<characterstic name="xxx1">
</characterstic>
<characterstic name="xxx2">
</characterstic>
<image id="xxx"></image>
</characteristics>
</sections>
<sections>
<characteristics>
<characterstic name="yyy1">
</characterstic>
<characterstic name="yyy2">
</characterstic>
<image id="yyy"></image>
</characteristics>
</sections>
</masters>
</Checkplan>
Image id xxx is common for xxx1 and xxx2 .
Image id yyy is common for yyy1 and yyy2 so i need to loop through only xxx related attributes from first iteration then i have
to read yyy reated in next iteration .
Iteration should run for each section .
XmlNodeList dataNodes = xml.SelectNodes("//Section");
foreach (XmlNode node in dataNodes)
{
foreach (XmlNode childNode in node.ChildNodes)
{
foreach (XmlNode childNode2 in childNode.ChildNodes)
{
FeatureName = childNode2.Attributes["Name"].Value;
LSL = Convert.ToInt32(childNode2.Attributes["LSL"].Value);
USL = Convert.ToInt32(childNode2.Attributes["USL"].Value);
}
}
if (!FeaturesCollection.ContainsKey(FeatureName))
{
FeaturesCollection.Add(FeatureName, new Features { m_Name = FeatureName, m_LSL = LSL, m_USL = USL, m_ImageID = imageid });
}

Using xml linq. You left an 'i' out of characteristic in the xml file. See code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("characteristics").Select(x => new {
id = (string)x.Element("image").Attribute("id"),
characteristics = x.Elements("characteristic").ToList().Select(y => (string)y.Attribute("name")).ToList()
}).ToList();
}
}
}

Related

Filter Attributes in Xml in c# AND modify the Xml

I am trying to convert and Xml A into Xml B using C#.
XML A
<root>
<country>
<city name="Boston" value="100">
<city name="Boston" value="200">
</country>
</root>
XMl B(Expected)
<root>
<country>
<city name="Boston" value="300">
</country>
</root>
C# code:
var doc = XDocument.Load(path);
var myDocument = new XmlDocument();
myDocument.Load(path);
var nodes = myDocument.GetElementsByTagName("city");
var resultNodes = new List<XmlNode>();
foreach (XmlNode node in nodes)
{
if (node.Attributes != null && node.Attributes["name"] != null && node.Attributes["name"].Value == "Boston")
resultNodes.Add(node);
foreach(var elements in resultNodes)
{
elements.Attributes.RemoveNamedItem("Boston");
}
}
Basically what i wanted to do here is add the 2 values(100 &200)from 2 different Boston attributes from XML A and print into a new XML B file but lost a bit here as what goes into this block.
foreach (XmlNode i in resultNodes)
{
}
Problems like this is easy to create new XElements. See code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> countries = doc.Descendants("country").ToList();
foreach (XElement oldCountry in countries)
{
XElement newCountry = new XElement("country");
var cities = oldCountry.Elements("city").GroupBy(x => (string)x.Attribute("name"));
foreach (var city in cities)
{
newCountry.Add(new XElement("city", new object[] { new XAttribute("name", city.Key), new XAttribute("value", city.Sum(x => (int)x.Attribute("value"))) }));
}
oldCountry.ReplaceWith(newCountry);
}
}
}
}

Replace the value by relying on the existing value in XML file

This is a sample XML file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Automation Test</string>
<string name="current_data_state_incoming_call">Incoming Call</string>
<string name="current_data_state_outgoing_call">Outgoing Call</string>
<string name="current_data_state_missed_call">Missed Call</string>
<string name="current_data_state_photo">Photo</string>
<string name="current_data_state_video">Video</string>
<string name="current_data_state_mp3">MP3</string>
<string name="current_data_state_voice_memo">Voice Memo</string>
<string name="current_data_state_phone_book">Phone Book</string>
<string name="current_data_state_phone_booksim">Phone Book(SIM)</string>
<string name="current_data_state_etc">Etc</string>
<string name="current_data_state_schedule">S Planner</string>
</resources>
I have a large file XML file and I want to replace the values in elements depending on their original value.
For example, I want to replace "Outgoing Call" with another word.
I tried this code:
XmlDocument xdoc = new XmlDocument();
xdoc.Load("strings.xml");
XmlElement root = xdoc.DocumentElement;
XmlNodeList elemList = root.GetElementsByTagName("string");
for (int i = 0; i < elemList.Count; i++)
{
xdoc.Save("strings.xml");
if (elemList[i].InnerText == "Incoming Call")
{
// xdoc.LoadXml(File.ReadAllText("strings.xml").Replace(elemList[i].InnerText, "صندوق"));
// MessageBox.Show(elemList[i].InnerText);
elemList[i].SelectSingleNode("resources/string").InnerText="مكالمات قادمة";
xdoc.Save("strings.xml");
}
}
and this code
XmlDocument xdoc = new XmlDocument();
xdoc.Load("strings.xml");
XmlNodeList aNodes = xdoc.SelectNodes("resources/string");
foreach (XmlNode node in aNodes)
{
XmlNode child1 = node.SelectSingleNode("string");
if(child1.InnerText == "Incoming Call")
{
child1.InnerText = "اتصالات قادمة";
}
}
xdoc.Save("strings.xml");
I can not replace the value.
===================================
thanx i solve my prob
var root2 = new XmlDocument();
root2.Load("strings.xml");
var root = new XmlDocument();
root.Load("strings2.xml");
foreach (XmlNode e1 in root2.GetElementsByTagName("string"))
{
string a = e1.Attributes["name"].Value;
foreach (XmlNode ee in root.GetElementsByTagName("string"))
{
string b = ee.Attributes["name"].Value;
if (a == b)
{
e1.FirstChild.Value = ee.FirstChild.Value;
}
}
}
root.Save("strings.xml");
I would use LINQ to XML for this. It makes all kinds of things much simpler than XmlDocument. Here's a complete example to perform a replacement (loading input.xml and writing output.xml):
using System;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
XDocument doc = XDocument.Load("input.xml");
ReplaceValue(doc, "Outgoing Call", "Other value");
doc.Save("output.xml");
}
static void ReplaceValue(XDocument doc, string original, string replacement)
{
foreach (var element in doc.Descendants("string").Where(x => x.Value == original))
{
element.Value = replacement;
}
}
}
You could easily change the method to throw an exception if it didn't find the value you were trying to replace, or if it found more than one element.
An alternative to replacing by value would be to replace by the name attribute, which would be a trivial change:
static void ReplaceNamedValue(XDocument doc, string name, string replacement)
{
foreach (var element in doc.Descendants("string")
.Where(x => (string) x.Attribute("name") == name))
{
element.Value = replacement;
}
}
You'd then call it like this:
ReplaceNamedValue(doc, "current_data_state_outgoing_call", "Other value");
You may want to create file on xml on the fly instead of replace. I prefer using the newer Net library xml linq (XDocument) rather than the older version XmlDocument. Here is an example of the code I would use :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string ident = "<?xml version=\"1.0\" encoding=\"utf-8\"?><resources></resources>";
XDocument doc = XDocument.Parse(ident);
XElement resources = doc.Root;
resources.Add(new XElement("string", new object[] {
new XAttribute("name","app_name"),
"Automation Test"
}));
resources.Add(new XElement("string", new object[] {
new XAttribute("name","current_data_state_incoming_call"),
"مكالمات قادمة"
}));
}
}
}
Here is code for replacement
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement resource = doc.Root;
Dictionary<string, XElement> dict = resource.Elements()
.GroupBy(x => (string)x.Attribute("name"), y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
if(dict.ContainsKey("app_name"))
{
dict["app_name"].SetValue("Automation Test");
}
if (dict.ContainsKey("current_data_state_incoming_call"))
{
dict["current_data_state_incoming_call"].SetValue("مكالمات قادمة");
}
}
}
}

Retrieving Xml Attribute Value in C#

I'm new to C# & I'm trying to read XML attribute from XML file in my Asp.net web project, when i retrieve attribute content i get this result :
"System.XML.Attribute;"
here is XML file:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<!--creating XML file-->
<Document PagesInDocument="1" Filename="YahyaXML">
<Page Filename="YahyaXML" ZonesInPage="1" PageID="0">
<Zone TextLinesInZone="2" zoneLRY="558" zoneLRX="1202"
zoneULY="3" zoneULX="886" ZoneID="0">
<TextLine Content="aaaaaaaaaaa" TextLineID="0"/>
<TextLine Content="aaaaaaaaaaaaaaaaaa" TextLineID="1"/>
</Zone>
</Page>
</Document>
Here is my c# code:
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\Program Files (x86)\NovoDynamics\NovoVerus\api\examples\C#Samples\WebAppTest\Uploads\test-ht.xml");
StringBuilder Content_Value = new StringBuilder();
XmlNodeList aNodes = doc.SelectNodes("/Document/Page/Zone");
XmlNodeList bNodes = doc.SelectNodes("/Document/Page/Zone/TextLine");
foreach (XmlNode aNode in aNodes)
{
XmlAttribute ULX_xml = aNode.Attributes["zoneULX"];
XmlAttribute ULY_xml = aNode.Attributes["zoneULY"];
XmlAttribute LRX_xml = aNode.Attributes["zoneLRX"];
XmlAttribute LRY_xml = aNode.Attributes["zoneLRY"];
if (ULX_xml.Value == TextBox5.Text && ULY_xml.Value == TextBox6.Text && LRX_xml.Value == TextBox7.Text && LRY_xml.Value == TextBox8.Text )
{
foreach (XmlNode bNode in bNodes)
{
//XmlAttribute ContentAttribute = bNode.Attributes["Content"];
if (bNode.Attributes["Content"].Value != null)
{
Content_Value.Append(bNode.Attributes["Content"].Value.ToString());
}
}
Content_Value.Append("\n");
}
}
TextBox9.Text = Content_Value.ToString();
Your code works. Try change first string in your xml file to:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
More: https://msdn.microsoft.com/en-us/library/ms256048(v=vs.120).aspx
Using xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
StreamReader reader = new StreamReader(FILENAME);
reader.ReadLine(); //skip identification
XDocument doc = XDocument.Load(reader);
var results = doc.Descendants("Page").Select(x => new
{
filename = (string)x.Attribute("Filename"),
page = (int)x.Attribute("ZonesInPage"),
id = (int)x.Attribute("PageID"),
zones = x.Elements("Zone").Select(y => new {
textLines = (int)y.Attribute("TextLinesInZone"),
ulx = (int)y.Attribute("zoneULX"),
uly = (int)y.Attribute("zoneULY"),
lrx = (int)y.Attribute("zoneLRX"),
lry = (int)y.Attribute("zoneLRY"),
textLine = y.Elements("TextLine").Select(z => new {
content = (string)z.Attribute("Content"),
id = (int)z.Attribute("TextLineID")
}).ToList()
}).ToList()
}).ToList();
}
}
}

Extracting values from serialized XML in C#

I have the following serialized XML :
<DataItem type="System.PropertyBagData" time="2017-02-03T09:50:29.1118296Z" sourceHealthServiceId="">
<Property Name="LoggingComputer" VariantType="8">g2aaS03OsX/9e5SSikdrVjFb4tkwhVUWeGh6pOv8nJ0=</Property>
<Property Name="EventDisplayNumber" VariantType="8">4502</Property>
<Property Name="ManagementGroupName" VariantType="8">/FTyfF2bs7hBhlQMJfSABYkkuTU98A80WiXu9TlL98w=</Property>
<Property Name="RuleName" VariantType="8">CollectNetMonInformation</Property>
<Property Name="ModuleTypeName" VariantType="8"/>
<Property Name="StackTrace" VariantType="8">System.Exception: [2/3/2017 9:50:29 AM][InitializeDataReceiver], CreateFile Error : 2 WaitNamedPipe Error : 2 Pipe guid is : d0c4c51e-543b-4f25-8453-40000066967d</Property>
</DataItem>
To extract the values of "Property" tags, i have written the following c# code:
using System.IO;
using System;
using System.Xml;
class Program
{
static void Main()
{
Console.WriteLine("Hello, World!");
string s = "<DataItem type=\"System.PropertyBagData\" time=\"2017-02-03T09:50:29.1118296Z\" sourceHealthServiceId=\"\"><Property Name=\"LoggingComputer\" VariantType=\"8\">g2aaS03OsX/9e5SSikdrVjFb4tkwhVUWeGh6pOv8nJ0=</Property><Property Name=\"EventDisplayNumber\" VariantType=\"8\">4502</Property><Property Name=\"ManagementGroupName\" VariantType=\"8\">/=</Property><Property Name=\"RuleName\" VariantType=\"8\">CollectNetMonInformation</Property><Property Name=\"ModuleTypeName\" VariantType=\"8\"></Property><Property Name=\"StackTrace\" VariantType=\"8\">System.Exception: [2/3/2017 9:50:29 AM][InitializeDataReceiver]: 2 WaitNamedPipe Error : 2 Pipe guid is : </Property></DataItem>";
XmlDocument xml = new XmlDocument();
xml.LoadXml(s);
XmlNodeList xnList = xml.SelectNodes("/DataItem");
foreach (XmlNode xn in xnList)
{
string firstName = xn["Property"].InnerText;
Console.WriteLine(firstName);
}
}
}
when i run the program, i get the output as "g2aaS03OsX/9e5SSikdrVjFb4tkwhVUWeGh6pOv8nJ0=" which is the value of first Property tag but no other value. How to fix this.
Thanks in advance.
Try this
string s = "<DataItem type=\"System.PropertyBagData\" time=\"2017-02-03T09:50:29.1118296Z\" sourceHealthServiceId=\"\"><Property Name=\"LoggingComputer\" VariantType=\"8\">g2aaS03OsX/9e5SSikdrVjFb4tkwhVUWeGh6pOv8nJ0=</Property><Property Name=\"EventDisplayNumber\" VariantType=\"8\">4502</Property><Property Name=\"ManagementGroupName\" VariantType=\"8\">/=</Property><Property Name=\"RuleName\" VariantType=\"8\">CollectNetMonInformation</Property><Property Name=\"ModuleTypeName\" VariantType=\"8\"></Property><Property Name=\"StackTrace\" VariantType=\"8\">System.Exception: [2/3/2017 9:50:29 AM][InitializeDataReceiver]: 2 WaitNamedPipe Error : 2 Pipe guid is : </Property></DataItem>";
XDocument doc = XDocument.Parse(s);
var NodeNames = doc.Descendants("DataItem").Elements();
foreach (var item in NodeNames)
{
string firstName = item.Value;
Console.WriteLine(firstName);
}
XDocument is newer than XmlDocument. More readable and you can use LINQ.
var xElements = XDocument.Parse(yourXml).Descendants("Property");
xElements.ToList().ForEach(x=> Console.WriteLine(x.Value));
You can use Linq to XML :
var results = from node in XDocument.Parse(s).Descendants()
where node.Name == "Property"
select node.Value;
Result :
try this code:
using System.IO;
using System;
using System.Xml;
class Program
{
static void Main()
{
Console.WriteLine("Hello, World!");
string s = "<DataItem type=\"System.PropertyBagData\" time=\"2017-02-03T09:50:29.1118296Z\" sourceHealthServiceId=\"64ced8f3-385a-238c-eea4-008bab8ba249\"><Property Name=\"LoggingComputer\" VariantType=\"8\">g2aaS03OsX/9e5SSikdrVjFb4tkwhVUWeGh6pOv8nJ0=</Property><Property Name=\"EventDisplayNumber\" VariantType=\"8\">4502</Property><Property Name=\"ManagementGroupName\" VariantType=\"8\">/FTyfF2bs7hBhlQMJfSABYkkuTU98A80WiXu9TlL98w=</Property><Property Name=\"RuleName\" VariantType=\"8\">CollectNetMonInformation</Property><Property Name=\"ModuleTypeName\" VariantType=\"8\">Microsoft.EnterpriseManagement.Mom.Modules.NetmonDataSource.NetmonDataSource</Property><Property Name=\"StackTrace\" VariantType=\"8\">System.Exception: [2/3/2017 9:50:29 AM][InitializeDataReceiver]Exception while trying to connect to the agent :Could not open pipe, CreateFile Error : 2 WaitNamedPipe Error : 2 Pipe guid is : d0c4c51e-543b-4f25-8453-40000066967d</Property></DataItem>";
XmlDocument xml = new XmlDocument();
xml.LoadXml(s);
XmlNodeList xnList = xml.SelectNodes("/DataItem/Property");
foreach (XmlNode xn in xnList)
{
string firstName = xn.InnerText;
Console.WriteLine(firstName);
}
}
}
Try this code:
Console.WriteLine("Hello, World!");
string s = "<DataItem type=\"System.PropertyBagData\" time=\"2017-02-03T09:50:29.1118296Z\" sourceHealthServiceId=\"\"><Property Name=\"LoggingComputer\" VariantType=\"8\">g2aaS03OsX/9e5SSikdrVjFb4tkwhVUWeGh6pOv8nJ0=</Property><Property Name=\"EventDisplayNumber\" VariantType=\"8\">4502</Property><Property Name=\"ManagementGroupName\" VariantType=\"8\">/=</Property><Property Name=\"RuleName\" VariantType=\"8\">CollectNetMonInformation</Property><Property Name=\"ModuleTypeName\" VariantType=\"8\"></Property><Property Name=\"StackTrace\" VariantType=\"8\">System.Exception: [2/3/2017 9:50:29 AM][InitializeDataReceiver]: 2 WaitNamedPipe Error : 2 Pipe guid is : </Property></DataItem>";
XmlDocument xml = new XmlDocument();
xml.LoadXml(s);
XmlNodeList xnList = xml.SelectNodes("/DataItem");
foreach (XmlNode xn in xnList)
{
XmlNodeList propsList = xn.SelectNodes("Property");
foreach (XmlNode node in propsList)
{
string firstName = node.InnerText;
Console.WriteLine(firstName);
}
}
I like using a dictionary in cases like this using xml linq to create the dictionary :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, string> dict = doc.Descendants("Property")
.GroupBy(x => (string)x.Attribute("Name"), y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}

How to get all attribute names from selected XML node in C#

This is my XML file. I need to select one test element and get all attributes name from its result child nodes.
<?xml version="1.0" encoding="UTF-8"?>
<summary>
<test>
<id>test 1</id>
<result value="-45">330</result>
<result value="0">300</result>
<result value="45">340</result>
</test>
<test>
<id>test 3</id>
<result value="-45">330</result>
<result value="0">300</result>
<result value="45">340</result>
</test>
</summary>
I wrote below code. but repeat same values and I want to stop it.
XmlDocument xd = new XmlDocument();
xd.Load(_xmlFilePath);
XmlNodeList nodelist = xd.GetElementsByTagName("result");
foreach (XmlNode node in nodelist)
{
string attrVal = node.Attributes["value"].Value;
Console.WriteLine(attrVal);
}
Any suggestion is appreciated.
Thanks.
You can use LINQ to Xml with XDocument class
var doc = XDocument.Load(_xmlFilePath);
var distinctResults = doc.Descendants("result")
.Select(element => element.Attribute("value").Value)
.Distinct();
foreach(var result in distinctResults)
{
Console.WriteLine(result);
}
Or with using of HashSet<string>
var results = doc.Descendants("result")
.Select(element => element.Attribute("value").Value);
var distinctResults = new HashSet<string>(results);
foreach(var result in distinctResults)
{
Console.WriteLine(result);
}
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication34
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
string id = "test 1";
var results = doc.Descendants("test").Where(x => (string)x.Element("id") == id).FirstOrDefault().Elements("result").Select(x => new
{
angle = (int)x.Attribute("value"),
length = (int)x
}).ToList();
}
}
}

Categories

Resources