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();
}
}
}
Related
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);
}
}
}
}
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("مكالمات قادمة");
}
}
}
}
<?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();
}
}
}
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();
}
}
}
<CustomerOrders>
<Customers>
<CustomerID>ALFKI</CustomerID>
<Orders>
<OrderID>10643</OrderID>
<CustomerID>ALFKI</CustomerID>
<OrderDate>1997-08-25</OrderDate>
</Orders>
<Orders>
<OrderID>10692</OrderID>
<CustomerID>ALFKI</CustomerID>
<OrderDate>1997-10-03</OrderDate>
</Orders>
<CompanyName>Alfreds Futterkiste</CompanyName>
</Customers>
<Customers>
<CustomerID>ANATR</CustomerID>
<Orders>
<OrderID>10308</OrderID>
<CustomerID>ANATR</CustomerID>
<OrderDate>1996-09-18</OrderDate>
</Orders>
<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
</Customers>
</CustomerOrders>
How do you retrieve OrderID,CustomerID and OrderDate? i have been trying it for hours already. Can someone help me? Thanks!
XmlNodeList xmlnode = doc.GetElementsByTagName("Customers");
HtmlGenericControl div = new HtmlGenericControl("div");
for(int i = 0; i < xmlnode.Count; i++)
{
Label lbl2 = new Label();
lbl2.Text = xmlnode[i].ChildNodes[1].Name;
div.Controls.Add(lbl2);
RadioButtonList rb1 = new RadioButtonList();
rb1.Items.Add(xmlnode[i].ChildNodes[1].InnerText+"<br>");
div.Controls.Add(rb1);
}
div1.Controls.Add(div);
You can use the XDocument class and its decendants. You can use XPath expressions to delve deeper into the code:
e.g.
using System.Xml.Linq
using System.Xml.XPath
....
XDocument doc= XDocument.Load("sample.xml");
XElement root= doc.Element("CustomerOrders");
var result= root.XPathSelectElements("Customers/CustomerId");
foreach(var customerid in result)
{
.....
}
Depending on what you want to achieve this should put you at the right track. While I was typing the answer, another answer proposes to use XmlDocument class. That should work as well, but when using XDocument you can use Linq, which adds a lot of flexibilty.
XmlDocument doc = new XmlDocument();
doc.LoadXml("yourxmldata");
XmlNodeList customers = doc.DocumentElement.SelectNodes("Customers");
foreach (XmlNode customer in customers)
{
XmlNodeList customerOrders = customer.SelectNodes("Orders");
string customername = customer["CustomerID"].InnerText;
foreach (XmlNode customerOrder in customerOrders)
{
string orderid = customerOrder["OrderID"].InnerText;
string orderdate = customerOrder["OrderDate"].InnerText;
}
}
Here is everything using Xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication47
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("Customers").Select(x => new
{
customerID = (string)x.Element("CustomerID"),
companyName = (string)x.Element("CompanyName"),
orders = x.Elements("Orders").Select(y => new {
orderID = (int)y.Element("OrderID"),
customerID = (string)y.Element("CustomerID"),
date = (DateTime)y.Element("OrderDate")
}).ToList()
}).ToList();
}
}
}