I have a problem with parse xml file to retrieve a names of tags. I have a following xml file:
<city version="1.2" last_updated="Thu, 28 Aug 2014 12:10:38 +0300">
<city id="8750">
<name>Лондон</name>
<name_en>London</name_en>
<region/>
<country>Великобритания</country>
<country_id>826</country_id>
</city>
<city id="110254">
<name>Лондон</name>
<name_en>London</name_en>
<region/>
<country>Канада</country>
<country_id>124</country_id>
</city>
<city id="58690">
<name>Лондон</name>
<name_en>London</name_en>
<region>Arkansas</region>
<country>Соединенные Штаты Америки</country>
<country_id>840</country_id>
</city>
<city id="65450">
<name>Лондон</name>
<name_en>London</name_en>
<region>Kentucky</region>
<country>Соединенные Штаты Америки</country>
<country_id>840</country_id>
</city>
<city id="76284">
<name>Лондон</name>
<name_en>London</name_en>
<region>Ohio</region>
<country>Соединенные Штаты Америки</country>
<country_id>840</country_id>
</city>
<city id="131">
<name>Макеевка</name>
<name_en>Makiivka</name_en>
<region>Донецкая область</region>
<country>Украина</country>
<country_id>804</country_id>
</city>
</city>
I want to do array or select list with all name of tag for example country. I have following code:
string filePath = String.Format("http://xml.weather.co.ua/1.2/city/?search={0}", name);
var xmlDocument = new XmlDocument();
xmlDocument.Load(filePath);
if (xmlDocument.DocumentElement != null)
foreach (XmlNode xmlNode in xmlDocument.GetElementsByTagName("city"))
yield return new SelectListItem
{
Text = xmlNode.Value,
Value = xmlNode.ToString()
};
}
How to solve this problem? Any idea?
Here is my idea but you have to create list "names" before. Try this LINQ to xml:
XDocument xDoc = XDocument.Load("your xml file");
foreach (var elem in xDoc.Document.Descendants("country"))
{
names.Add(elem.Name);
}
If you can modify an xml to for me more clear form like that:
<city id="8750" name="Лондон" name_en="London" region="" country="Великобритания" country_en="826"/>
What for create that number of tags with only names?
Than u can do that:
XDocument xDoc = XDocument.Load("your xml file");
foreach (var elem in xDoc.Document.Descendants("city"))
{
names.Add(elem.Attribute("name").Value);
name_en.Add(elem.Attribute("name_en").Value);
(...)
}
"I want to do array or select list with all name of tag for example country."
"I want get all value with tag country and I do not know how"
You can try using XDocument to get array of country names :
string url = "http://xml.weather.co.ua/1.2/city/?search=%D0%BB%D0%BE%D0%BD%D0%B4%D0%BE%D0%BD";
XDocument doc = XDocument.Load(url);
var countries = doc.Descendants("city")
.Elements("country")
.Select(o => (string)o)
.ToArray();
Related
Pretty new at C# so trying to learn xml serialization. I have an xml setup like the following:
<Guy>
<Name>
<Root>
<Entry>
<Favorite> his favorite food is sushi </Favorite>
</Entry>
</Root>
</Name>
</Guy>
I need to select the "Favorite" tags and return the "his favorite food is sushi". What is the simplest way to go about this in C#? Can XDocument and LINQ extensions be used?
string xml = #"
<Guy>
<Name>
<Root>
<Entry>
<Favorite> his favorite food is sushi </Favorite>
</Entry>
</Root>
</Name>
</Guy>";
var doc = XDocument.Parse(xml);
Console.WriteLine(doc.Descendants("Favorite").First().Value);
// or
foreach(var item in doc.Descendants("Favorite").Select(e => e.Value))
{
Console.WriteLine(item);
}
https://dotnetfiddle.net/Iagop5
You can try this approach using XPathNavigator:
public static string GetAttribute(string xml, string nodeName) {
StringReader stringReader = new StringReader(xml);
XPathDocument doc = new XPathDocument(stringReader);
XPathNavigator xNav = doc.CreateNavigator();
XPathNavigator node = xNav.SelectSingleNode("//" + nodeName);
return node != null ? node.InnerXml : string.Empty;
}
Here's a reference: https://learn.microsoft.com/en-us/dotnet/api/system.xml.xpath.xpathnavigator.selectsinglenode?view=net-6.0
I am using WebRequest and WebReponse classes to get a response from a web api. The response I get is an xml of the following format
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<A></A>
<B></B>
<C></C>
<D>
<E NAME="aaa" EMAIL="a#a.com"/>
<E NAME="bbb" EMAIL="b#b.com"/>
</D>
</ROOT>
I want to get all the E elements as a List<E> or something.
Can some one guide me on this pls.
if you want to avoid serialization, as you only want a very specific part of the xml, you can do this with one LINQ statement:
var items = XDocument.Parse(xml)
.Descendants("E")
.Select(e => new
{
Name = e.Attribute("NAME").Value,
Email = e.Attribute("EMAIL").Value
})
.ToList();
Working example:
var doc = XDocument.Parse(#"<?xml version='1.0' encoding='UTF-8'?>
<ROOT>
<A></A>
<B></B>
<C></C>
<D>
<E NAME='aaa' EMAIL='a#a.com'/>
<E NAME='bbb' EMAIL='b#b.com'/>
</D>
</ROOT>");
var elements = from el in doc.Elements()
from el2 in el.Elements()
from el3 in el2.Elements()
where el3.Name == "E"
select el3;
foreach (var e in elements)
{
Console.WriteLine(e);
}
Hi below is a sample of the xml i am using. I been through allsorts of options I can think of to be able to start at the personData node and iterate the results, and nothing i seem to try works unless I navigate manually through each child node from the root down. Can anyone advise on how I can do this without starting at the root
My code currently is
using (var r = File.OpenText(#"C:\S\sp.xml"))
{
XPathDocument document = new XPathDocument(XmlReader.Create(r));
XPathNavigator xPathNav = document.CreateNavigator();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xPathNav.NameTable);
nsmgr.AddNamespace("g2", "http://person.transferobject.com/xsd");
XPathNodeIterator xni = xPathNav.Select("/g2:companys/g2:company/g2:person/g2:personData", nsmgr);
foreach (XPathNavigator nav in xni)
Console.WriteLine(nav.Name);
}
Xml
<?xml version="1.0" encoding="UTF-8"?>
<Header xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<dataSource xmlns="http://person.transferobject.com/xsd">IG2</dataSource>
<dateTime xmlns="http://person.transferobject.com/xsd">Thu Mar 21 15:56:42 GMT 2013</dateTime>
<formatVersion xmlns="http://person.transferobject.com/xsd">2.0</formatVersion>
<companys xmlns="http://person.transferobject.com/xsd">
<company>
<errorMessages xsi:nil="true"/>
<person>
<personData>
<address>
<address1 xmlns="http://transferobject.com/xsd">37 Smith St</address1>
<county xmlns="http://transferobject.com/xsd">COUNTY-37</county>
<postcode xmlns="http://transferobject.com/xsd">Po12 123</postcode>
</address>
<basicDetails>
<currentFirstName xmlns="http://transferobject.com/xsd">Fred</currentFirstName>
<currentLastName xmlns="http://transferobject.com/xsd">Bloggs</currentLastName >
<currentStage xmlns="http://transferobject.com/xsd">H1</currentStage>
<currentGroup xmlns="http://transferobject.com/xsd">3</currentGroup>
<dob xmlns="http://transferobject.com/xsd">2000-04-25</dob>
<email xmlns="http://transferobject.com/xsd">AN#AN.AOM</email>
<entryDate xmlns="http://transferobject.com/xsd">2003-09-03</entryDate>
</basicDetails>
</personData>
<personData>
<address>
<address1 xmlns="http://transferobject.com/xsd">37 Smith St</address1>
<county xmlns="http://transferobject.com/xsd">COUNTY-37</county>
<postcode xmlns="http://transferobject.com/xsd">Po12 123</postcode>
</address>
<basicDetails>
<currentFirstName xmlns="http://transferobject.com/xsd">John</currentFirstName>
<currentLastName xmlns="http://transferobject.com/xsd">Bloggs</currentLastName >
<currentStage xmlns="http://transferobject.com/xsd">H1</currentStage>
<currentGroup xmlns="http://transferobject.com/xsd">3</currentGroup>
<dob xmlns="http://transferobject.com/xsd">1999-04-25</dob>
<email xmlns="http://transferobject.com/xsd">AN#AN.AOM</email>
<entryDate xmlns="http://transferobject.com/xsd">2003-09-03</entryDate>
</basicDetails>
</personData>
</person>
</company>
</companys>
</header>
I know you're using XPath, but as you have an answer with XPath I'll give one using Linq
using System;
using System.Linq;
using System.Xml.Linq;
namespace xmlTest
{
class Program
{
static void Main()
{
XDocument doc = XDocument.Load("C:\\Users\\me\\Desktop\\so.xml");
var personDataDetails = (from p in doc.Descendants().Elements()
where p.Name.LocalName == "personData"
select p);
foreach (var item in personDataDetails)
{
Console.WriteLine(item.ToString());
}
Console.ReadKey();
}
}
}
Are you just asking how you can iterate through the personData nodes without listing the full path? If that's what you want to do, you can just do this:
XPathNodeIterator xni = xPathNav.Select("//g2:personData", nsmgr);
I have an XML in a string variable i want to check if this xml content contains
<xml>
<message display='yes'>
....
or
<xml>
<xdp:xdp>
...
is it possible?
Here is how you can check for it:
string example = #"<xml>
<message display='yes'></message>
</xml>";
XDocument doc = XDocument.Parse(example);
if (doc.Element("xml").Element("message") != null)
{
// node "message" exists within node "xml" which is located at the root of the document
}
You can use XDocument class to check for existence of any node at any location in the hierarchy of an XML document. You can load contents from string or file easily.
An example below
<Order>
<AmazonOrderID>000-1111111-2222222</AmazonOrderID>
<MerchantOrderID>111-3333333-4444444</MerchantOrderID>
<PurchaseDate>2012-03-02T13:28:53+00:00</PurchaseDate>
<LastUpdatedDate>2012-03-02T13:29:05+00:00</LastUpdatedDate>
<OrderStatus>Pending</OrderStatus>
<SalesChannel>Amazon.com</SalesChannel>
<URL>http://www.amazon.com</URL>
<FulfillmentData>
<FulfillmentChannel>Amazon</FulfillmentChannel>
<ShipServiceLevel>Standard</ShipServiceLevel>
<Address>
<City>Beverly Hills</City>
<State>CA</State>
<PostalCode>90210-1234</PostalCode>
<Country>US</Country>
</Address>
</FulfillmentData>
<OrderItem>
<ASIN>AmazonASIN </ASIN>
<SKU> Internal-SKU</SKU>
<ItemStatus>Pending</ItemStatus>
<ProductName> This is the name of the product </ProductName>
<Quantity>1</Quantity>
<ItemPrice>
<Component>
<Type>Principal</Type>
<Amount currency="USD">19.99</Amount>
</Component>
</ItemPrice>
</OrderItem>
</Order>
List<string> getNodes(string path, string nodeName) {
List<string> nodes = new List<string>();
XDocument xmlDoc = XDocument.Load(path); //Create the XML document type
foreach (var el in xmlDoc.Descendants(nodeName)) {
//for debugging
//nodes.Add(el.Name + " " + el.Value);
//for production
nodes.Add(el.Value);
}
return nodes;
} //end getNodes
List<string> skuNodes = xml.getNodes(#"AmazonSalesOrders.xml", "SKU");
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Report SYSTEM "https://abc.mycompany.com/abc/processingreports/processeddtd/abcd_1_8.dtd">
<Report Name="Daily TRANSACTIONS"
Version="1.8"
xmlns="https://abc.mycompany.com/abc/processingreports/processeddtd/abcd_1_8.dtd"
OrgID="ABC_PQR" StartDate="2011-03-10T00:00:00+00:00" EndDate="2011-03-11T00:00:00+00:00">
<Requests>
<Request ID="2"
Date="2011-03-10T00:21:14+00:00"
OrderNumber="1">
<BillTo>
<FirstName />
</BillTo>
<LineItems>
<LineItem Number="0">
<Quantity />
</LineItem>
</LineItems>
</Request>
<Request ID="2"
Date="2011-03-10T00:21:14+00:00"
OrderNumber="1">
TransactionNumber="389958330911111">
<BillTo>
<FirstName>A</FirstName>
</BillTo>
<LineItems>
<LineItem Number="0">
<Quantity>1</Quantity>
</LineItem>
</LineItems>
<UniqueData>
<UniqueNumber>11111111111111111111111111111</UniqueNumber>
</UniqueData></Request></Requests></Report>
In above XML file using Linq i just
want to extract OrderNumber and
UniqueNumber
OrderNumber="1"
11111111111111111111111111111
Any ideas, suggestions to extract these details?
I can select elements from above xml file but UniqueNumber is not associated with OrderNumber
I am looking for something below (ignore lines where UniqueNumber is not present)
OrderNumber - assosicated UniqueNumber
Update
In "requiredElements" i am expecting two coulmns OrderNumber and UniqueNumber and holding associated values with each other as 1 and 11111 and so one
#region FileOpen with UTF8 Encoding
TextReader sr = new StreamReader(cFileName, Encoding.UTF8);
XDocument reportfile = XDocument.Load(sr, LoadOptions.SetBaseUri);
XElement xd = XElement.Parse(reportfile.ToString());
sr.Close();
#endregion
XNamespace ns = xd.Attribute("xmlns").Value;
var requiredElements = (from resultquery in reportfile.Descendants()
select new
{
OrderNumber = resultquery.Attribute("OrderNumber"),
UniqueNumber= (string)resultquery.Element(AddNameSpace(ns, "UniqueNumber")),
}
);
Here is some sample:
XDocument doc = XDocument.Load(#"file.xml");
XNamespace df = doc.Root.Name.Namespace;
var results = from request in doc.Descendants(df + "Request")
where request.Elements(df + "UniqueData").Elements(df + "UniqueNumber").Any()
select new
{
ordNumber = (int)request.Attribute("OrderNumber"),
uniqueNumber = (decimal)request.Element(df + "UniqueData").Element(df + "UniqueNumber")
};
foreach (var result in results)
{
Console.WriteLine("{0}-{1}", result.ordNumber, result.uniqueNumber);
}