I have an xml file. I want to query a peer node in C#.
For ex: For a given input xml file as below,
i want to query the title using the artist as an input. How do i do this ??
i.e Input --> Pink Floyd, Output -----> Division Bell ..
<catalog>
<cd>
<title>Division Bell<title>
<artist>Pink Floyd<artist>
<price>29$<price>
</cd>
<cd>
<title>Relapse<title>
<artist>Eminem<artist>
<price>19$<price>
</cd>
</catalog>
You could use a XDocument:
using System;
using System.Linq;
using System.Xml.Linq;
class Program
{
static void Main()
{
var doc = XDocument.Load("test.xml");
var result =
(from cd in doc.Root.Descendants("cd")
let artist = cd.Element("artist")
let title = cd.Element("title")
where artist != null && title != null && artist.Value == "Pink Floyd"
select title.Value
).FirstOrDefault();
Console.WriteLine(result);
}
}
Its quite easy tor read xml in .net
XDocument loaded = XDocument.Load(#"C:\youxml.xml");
var query = from xElem in loaded.Descendants("cd")
where xElem.Element("artist").Value == "Eminem"
select new Friend
{
Title = xElem.Attribute("title").Value
};
Make use of Linq To XML or XLINQ will resolve you issue easily.
Also check this : http://msdn.microsoft.com/en-us/library/bb308960.aspx
You can also use XPath syntax.
here is an example:
string inputArtist = "Pink Floyd";
var doc = XDocument.Load("test.xml");
XmlNode cdTitleNode = doc.SelectSingleNode("//cd[artist='" + inputArtist + "']/title");
string outputTitle = cdTitleNode.InnerText;
There is an excellent XPATH simulator on http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm to try you Xpath expressions.
You can also found a good tutorial there, but a fast search on the web will result in many web pages explaining all about XPath usage and syntax.
Using XPath, you can return a match:
using System.Xml;
using System.Xml.XPath;
public string QuerySearch(string file, string artist) {
// create an XML Document and load the file
XmlDocument xd = new XmlDocument();
xd.Load(file);
// get the root xml element
XmlElement root = xd.DocumentElement;
// get the list of artists
XmlNodeList aristList = root.GetElementsByTagName("artist");
// get the list of titles's
XmlNodeList titleList = root.GetElementsByTagName("title");
// find match
for (int i = 0;i < aristList.Count; i++) {
if (aristList.Item(i).InnerText == artist) {
return titleList.Item(i).InnerText
}
}
return "no match found.";
}
Related
I have xml stored in string variable. from that xml I need to filter data based on StandardValue. I want to extract only those records whose StandardValue is not null & not empty. I tried but my code did not work.
string xmldoc= #"<?xml version=""1.0"" encoding=""utf-8""?>
<TickerBrokerStandardDateLineitem>
<Ticker />
<TickerID />
<TickerBrokerStandardDateLineitemValues>
<TickerBrokerStandardDateLineitemValue>
<TabName>Consensus Model</TabName>
<StandardDate>1Q 2010</StandardDate>
<BRTab>Income Statement</BRTab>
<BRLineItem>NET REVENUES</BRLineItem>
<Action>Extracted</Action>
<StandardLineItem>Net Revenue</StandardLineItem>
<StandardValue>329.623</StandardValue>
</TickerBrokerStandardDateLineitemValue>
<TickerBrokerStandardDateLineitemValue>
<TabName>Consensus Model</TabName>
<StandardDate>2Q 2010</StandardDate>
<BRTab>Income Statement</BRTab>
<BRLineItem>NET REVENUES</BRLineItem>
<Action>Extracted</Action>
<StandardLineItem>Net Revenue</StandardLineItem>
<StandardValue></StandardValue>
</TickerBrokerStandardDateLineitemValue>
<TickerBrokerStandardDateLineitemValue>
<TabName>Consensus Model</TabName>
<StandardDate>2Q 2010</StandardDate>
<BRTab>Income Statement</BRTab>
<BRLineItem>NET REVENUES</BRLineItem>
<Action>Extracted</Action>
<StandardLineItem>Net Revenue</StandardLineItem>
<StandardValue/>
</TickerBrokerStandardDateLineitemValue>
</TickerBrokerStandardDateLineitemValues>
</TickerBrokerStandardDateLineitem>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmldoc);
XmlNodeList nodeList = doc.GetElementsByTagName("TickerBrokerStandardDateLineitemValue");
List<string> list = new List<string>();
foreach (XmlNode item in nodeList)
{
foreach (XmlElement i in item)
{
if (i.Name == "StandardValue")
{
if (i.InnerText == string.Empty)
{
list.Add(item.OuterXml);
}
}
}
}
string a = string.Empty;
foreach (var item in list)
{
a = doc.InnerXml.Replace(item, "");
}
string str1 = doc.OuterXml;
My above code does not work. basically how to filter with xpath that return only those records whose StandardValue is not null & not empty.
How to achieve it with XmlDocument class instead of xdocument.
At end I have to stored filtered record's xml into string. I know XmlDocument class has outer xml property which return full xml.
Give me sample code which will return filter records & stored filter records xml into string.
Use xml linq which is the newer version of the Net xml library :
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)
{
string xml = File.ReadAllText(FILENAME);
XDocument doc = XDocument.Parse(xml);
List<XElement> tickerBrokerStandardDateLineitemValues = doc.Descendants("TickerBrokerStandardDateLineitemValue")
.Where(x => (x.Element("StandardValue") != null) && ((string)x.Element("StandardValue") != string.Empty))
.ToList();
}
}
}
Assuming the input string your provided in the question.
This will select all TickerBrokerStandardDateLineitemValue values that has StandardValue element and it's not empty or white space (normalize-space).
normalize-space:
strips leading and trailing white-space from a string, replaces
sequences of whitespace characters by a single space, and returns the
resulting string.
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlStr); // <input from the question>
var nodes = xmlDoc.SelectNodes("//TickerBrokerStandardDateLineitemValue[StandardValue and string-length(normalize-space(StandardValue))]");
I am trying to figure out the code to extract xml child (I think this is worded correctly) elements. I have searched and tried many samples but cannot find how to drill down to pick out the section I want and return the information I need. Maybe I all I need is someone to define the data I am trying to pull so I can read up on the issue, of course any code would be very helpful and I will figure it out from there. Thanks in advanced for any help!
Here is the xml file. I am trying to run an if statement to find the section named <STATISTICTYPE>PVCAP_CharactersSaved</STATISTICTYPE> and return the <JOBNAME>,<TIMEDELTA>,<VALUESUM>.
<?xml version="1.0" encoding="utf-8"?>
<PVCAPTURESTATISTICCONTAINTER xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PVCAPTUREJOBSTATISTICS>
<PVCAPTURESTATISTICSUMMARY>
<STATISTICTYPE>PVCAP_CharactersSaved</STATISTICTYPE>
<STATISTICNAME>Characters saved</STATISTICNAME>
<JOBID>24</JOBID>
<JOBNAME>HEAT FILES</JOBNAME>
<TIMEDELTA>422</TIMEDELTA>
<VALUESUM>25432</VALUESUM>
</PVCAPTURESTATISTICSUMMARY>
<PVCAPTURESTATISTICSUMMARY>
<STATISTICTYPE>PVCAP_CharactersSaved_NoMM</STATISTICTYPE>
<STATISTICNAME>Characters saved (no match and merge)</STATISTICNAME>
<JOBID>24</JOBID>
<JOBNAME>HEAT FILES</JOBNAME>
<TIMEDELTA>422</TIMEDELTA>
<VALUESUM>25432</VALUESUM>
</PVCAPTURESTATISTICSUMMARY>
</PVCAPTUREJOBSTATISTICS>
<DOCUMENTCOUNT>762</DOCUMENTCOUNT>
<PAGECOUNT>3194</PAGECOUNT>
<IMAGECOUNT>3194</IMAGECOUNT>
<VERSION>2.0</VERSION>
</PVCAPTURESTATISTICCONTAINTER>
You can use LINQ to XML, particularly the XElement class.
var element = XElement.Parse(xmlStr).Element("PVCAPTUREJOBSTATISTICS")
.Elements("PVCAPTURESTATISTICSUMMARY")
.First(c => c.Element("STATISTICTYPE").Value == "PVCAP_CharactersSaved")
var jobName = element.Element("JOBNAME").Value;
var timeDelta = element.Element("TIMEDELTA").Value;
var valueSum = element.Element("VALUESUM").Value;
You'll want to add in some error handling and whatnot here, but this should get you going in the right direction.
You can do something like this:
XElement res = XElement.Parse(xmlResult);
foreach(var elem in res.Element("PVCAPTUREJOBSTATISTICS").Elements("PVCAPTURESTATISTICSUMMARY"))
{
if (elem.Element("STATISTICTYPE").Value.Equals("PVCAP_CharactersSaved", StringComparison.Ordinal))
{
string jobName = elem.Element("JOBNAME").Value;
string timeDelta = elem.Element("TIMEDELTA").Value;
string valueSum = elem.Element("VALUESUM").Value;
}
}
You can use XDocument and LINQ-to-XML to do that quite easily, for example :
string xml = "your xml content here";
XDocument doc = XDocument.Parse(xml);
//or if you have the xml file instead :
//XDocument doc = XDocument.Load("path_to_xml_file.xml");
var result = doc.Descendants("PVCAPTURESTATISTICSUMMARY")
.Where(o => (string) o.Element("STATISTICTYPE") == "PVCAP_CharactersSaved")
.Select(o => new
{
jobname = (string) o.Element("JOBNAME"),
timedelta = (string) o.Element("TIMEDELTA"),
valuesum = (string) o.Element("VALUESUM")
});
foreach (var r in result)
{
Console.WriteLine(r);
}
Hey all i have looked thoroughly through all the questions containing XDocument and while they are all giving an answer to what I'm looking for (mostly namespaces issues) it seems it just won't work for me.
The problem I'm having is that I'm unable to select any value, be it an attribute or element.
Using this XML
I'm trying to retrieve the speaker's fullname.
public void GetEvent()
{
var xdocument = XDocument.Load(#"Shared\techdays2013.xml");
XNamespace xmlns = "http://www.w3.org/2001/XMLSchema-instance";
var data = from c in xdocument.Descendants(xmlns + "speaker")
select c.Element(xmlns + "fullname").Value;
}
You can omit the namespace declaration in your linq statement.
public void GetEvent()
{
var xdocument = XDocument.Load(#"Shared\techdays2013.xml");
//XNamespace xmlns = "http://www.w3.org/2001/XMLSchema-instance";
var data = from c in xdocument.Descendants("speaker")
select c.Element("fullname").Value;
}
You can omit WebClient because you have direct local access to a file. I'm just showing a way to process your file on my machine.
void Main()
{
string p = #"http://events.feed.comportal.be/agenda.aspx?event=TechDays&year=2013&speakerlist=c%7CExperts";
using (var client = new WebClient())
{
string str = client.DownloadString(p);
var xml = XDocument.Parse(str);
var result = xml.Descendants("speaker")
.Select(speaker => GetNameOrDefault(speaker));
//LinqPad specific call
result.Dump();
}
}
public static string GetNameOrDefault(XElement element)
{
var name = element.Element("fullname");
return name != null ? name.Value : "no name";
}
prints:
Bart De Smet
Daniel Pearson
Scott Schnoll
Ilse Van Criekinge
John Craddock
Corey Hynes
Bryon Surace
Jeff Prosise
1) You have to drop the namespace
2) You'll have to query more precisely. All your <speaker> elements inside <speakers> have a fullname but in the next section I spotted <speaker id="94" />
A simple fix (maybe not the best) :
//untested
var data = from c in xdocument.Root.Descendants("speakers").Descendants("speaker")
select c.Element("fullname").Value;
You may want to specify the path more precise:
xdocument.Element("details").Element("tracks").Element("speakers").
I need to get the xml path opf the xml file by providing the value of an xml child element as the input.
For example:
XML file:
<?xml version="1.0"?>
<document-inquiry xmlns="http://ops.epo.org">
<publication-reference data-format="docdb" xmlns="http://www.epo.org/exchange">
<document-id>
<country>EP</country>
<doc-number>1000</doc-number>
<kind>A1</kind>
</document-id>
</publication-reference>
</document-inquiry>
For the above XML file. I need to get the XML path by using the value "1000".
If my input is value of the element "1000"
Output i need is :
<document-id>
<country>EP</country>
<doc-number>1000</doc-number>
<kind>A1</kind>
</document-id>
I need to achieve this using c# code. Can anyone please help me out on this...
You could use XPathSelectElement extension method:
using System;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
class Program
{
static void Main()
{
var doc = XDocument.Load("test.xml");
var ns = new XmlNamespaceManager(new NameTable());
ns.AddNamespace("ns", "http://www.epo.org/exchange");
var elem = XDocument.Load("test.xml")
.XPathSelectElement("//ns:document-id[ns:doc-number='1000']", ns);
if (elem != null)
{
Console.WriteLine(elem.ToString());
}
}
}
You could use XPathSelectElements if you want to select multiple nodes that correspond to this criteria.
You can select the element that you want with a linq query.
var number = "1000";
var xml = XDocument.Parse( xml_string );
XNamespace ns = "http://www.epo.org/exchange";
var result = (from data in xml.Descendants(ns + "document-id")
where data.Element(ns + "doc-number").Value == number
select data).FirstOrDefault();
.FirstOrDefault() returns the first matching element or null. You could instead use .List() to get a list containing all matching elements.
I have several XML files that I wish to read attributes from. My main objective is to apply syntax highlighting to rich text box.
For example in one of my XML docs I have: <Keyword name="using">[..] All the files have the same element: Keyword.
So, how can I get the value for the attribute name and put them in a collection of strings for each XML file.
I am using Visual C# 2008.
The other answers will do the job - but the syntax highlighting thingy and the several xml files you say you have makes me thinks you need something faster, why not use a lean and mean XmlReader?
private string[] getNames(string fileName)
{
XmlReader xmlReader = XmlReader.Create(fileName);
List<string> names = new List<string>();
while (xmlReader.Read())
{
//keep reading until we see your element
if (xmlReader.Name.Equals("Keyword") && (xmlReader.NodeType == XmlNodeType.Element))
{
// get attribute from the Xml element here
string name = xmlReader.GetAttribute("name");
// --> now **add to collection** - or whatever
names.Add(name);
}
}
return names.ToArray();
}
Another good option would be the XPathNavigator class - which is faster than XmlDoc and you can use XPath.
Also I would suggest to go with this approach only IFF after you try with the straightforward options you're not happy with performance.
You could use XPath to get all the elements, then a LINQ query to get the values on all the name atttributes you find:
XDocument doc = yourDocument;
var nodes = from element in doc.XPathSelectElements("//Keyword")
let att = element.Attribute("name")
where att != null
select att.Value;
string[] names = nodes.ToArray();
The //Keyword XPath expression means, "all elements in the document, named "Keyword".
Edit: Just saw that you only want elements named Keyword. Updated the code sample.
Like others, I would suggest using LINQ to XML - but I don't think there's much need to use XPath here. Here's a simple method to return all the keyword names within a file:
static IEnumerable<string> GetKeywordNames(string file)
{
return XDocument.Load(file)
.Descendants("Keyword")
.Attributes("name")
.Select(attr => attr.Value);
}
Nice and declarative :)
Note that if you're going to want to use the result more than once, you should call ToList() or ToArray() on it, otherwise it'll reload the file each time. Of course you could change the method to return List<string> or string[] by -adding the relevant call to the end of the chain of method calls, e.g.
static List<string> GetKeywordNames(string file)
{
return XDocument.Load(file)
.Descendants("Keyword")
.Attributes("name")
.Select(attr => attr.Value)
.ToList();
}
Also note that this just gives you the names - I would have expected you to want the other details of the elements, in which case you'd probably want something slightly different. If it turns out you need more, please let us know.
You could use LINQ to XML.
Example:
var xmlFile = XDocument.Load(someFile);
var query = from item in xmlFile.Descendants("childobject")
where !String.IsNullOrEmpty(item.Attribute("using")
select new
{
AttributeValue = item.Attribute("using").Value
};
You'll likely want to use XPath. //Keyword/#name should get you all of the keyword names.
Here's a good introduction: .Net and XML XPath Queries
**<Countries>
<Country name ="ANDORRA">
<state>Andorra (general)</state>
<state>Andorra</state>
</Country>
<Country name ="United Arab Emirates">
<state>Abu Z¸aby</state>
<state>Umm al Qaywayn</state>
</Country>**
public void datass(string file)
{
string file = HttpContext.Current.Server.MapPath("~/App_Data/CS.xml");
XmlDocument doc = new XmlDocument();
if (System.IO.File.Exists(file))
{
//Load the XML File
doc.Load(file);
}
//Get the root element
XmlElement root = doc.DocumentElement;
XmlNodeList subroot = root.SelectNodes("Country");
for (int i = 0; i < subroot.Count; i++)
{
XmlNode elem = subroot.Item(i);
string attrVal = elem.Attributes["name"].Value;
Response.Write(attrVal);
XmlNodeList sub = elem.SelectNodes("state");
for (int j = 0; j < sub.Count; j++)
{
XmlNode elem1 = sub.Item(j);
Response.Write(elem1.InnerText);
}
}
}