Here is my xml file
<?xml version="1.0" encoding="ASCII"?>
<Vitals>
<Vendor>General Electric Healthcare</Vendor>
<Model>Pro/Procare</Model>
<Result name="Mean_arterial_pressure">
<Value>86</Value>
<Units name="mmHg"></Units>
<Time_stamp year="2008" month="11" day="18" hour="12" minute="33" second="14"></Time_stamp>
</Result>
<Result name="Systolic_blood_pressure">
<Value>130</Value>
<Units name="mmHg"></Units>
<Time_stamp year="2008" month="11" day="18" hour="12" minute="33" second="14"></Time_stamp>
</Result>
<Result name="Diastolic_blood_pressure">
<Value>67</Value>
<Units name="mmHg"></Units>
<Time_stamp year="2008" month="11" day="18" hour="12" minute="33" second="14"></Time_stamp>
</Result>
<Result name="Pulse">
<Value>73</Value>
<Units name="BPM"></Units>
<Method>blood_pressure</Method>
<Time_stamp year="2008" month="11" day="18" hour="12" minute="33" second="14"></Time_stamp>
</Result>
</Vitals>
and Here is my sourcecode, I having the issue how to get the result name and the value?
private void btnReadXml_Click(object sender, EventArgs e)
{
Hashtable h = new Hashtable();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("C:\\dinamap.xml");
XmlNodeList doc_results = xmlDoc.GetElementsByTagName("Vitals/Vendor/Model/Result[#name='Systolic_blood_pressure']");
foreach (XmlNode pnode in doc_results)
{
foreach (XmlNode cnode in pnode.ChildNodes)
{
if (cnode.Name == "Value")
{
h.Add(pnode.Attributes["name"].InnerText + cnode.Name, cnode.Attributes["name"].InnerText);
}
else
{
h.Add(pnode.Attributes["name"].InnerText + "_" + cnode.Name, cnode.InnerText);
}
}
}
}
May I know what wrong of my code? always can't get the value.
I need to get the value from xml file.
On line 5, your xPath specify Model is a child of Vendor while Vendor contains only a string (<Vendor>General Electric Healthcare</Vendor>).
Moreover, to navigate with xPath i advice you to use SelectNodes function.
Try this instead :
XmlNodeList doc_results = xmlDoc.SelectNodes("/Vitals/Model/Result[#name='Systolic_blood_pressure']");
It'd be easier if you used LINQ to XML for this.
var doc = XDocument.Load("path/to/xml");
var results =
from result in doc.Descendants("Result")
select new
{
Name = (string) result.Attribute("name"),
Value = (string) result.Element("Value"),
Units = (string) result.Element("Units").Attribute("name")
};
You could then filter by Name if you needed:
var sysBp = results.Single(x => x.Name == "Systolic_blood_pressure");
See this fiddle for a working demo.
You're currently trying to retrieve the "name" attribute of the child node, which it does not actually have in the case of your value node. If you use cnode.Value you can get the contents of a text note.
Also, Result is not a child of Model, which is not a child of Vendor. You'll either want to properly make them children or change the path you're setting for doc_results
private void btnReadXml_Click(object sender, EventArgs e)
{
var doc = XDocument.Load("C:\\dinamap.xml");
var results = from result in doc.Descendants("Result")
select new
{
Name = (string)result.Attribute("name"),
Value = (string)result.Element("Value"),
Units = (string)result.Element("Units").Attribute("name")
};
foreach (var result in results)
{
MessageBox.Show("{result.Name}: {result.Value} {result.Units}");
}
}
Related
I want to select the value of the "data" attribute where the "key" attribute matches a specific search.
The XML file will look like this.
<connections>
<production>
<connection key="KEY1" data="value1" />
<connection key="KEY2" data="value2" />
<connection key="KEY3" data="value3" />
</production>
</connections>
So is there a way to return the value of the data attribute by searching for key = key1 for example?
You could do something like this if you wanted to avoid using XPath.
using System.Xml.Linq;
var xmlStr = File.ReadAllText("Testfile.xml");
XElement root = XElement.Parse(xmlStr);
var data = root.Element("production")
.Elements().Where(x => x.Attribute("key").Value == "KEY1")
.Select(x=>x.Attribute("data").Value)
.First();
Console.WriteLine(data);
Try this, using System.Xml you can read the xml file in question and iterate through the nodes to look for your value.
private void YOUR_METHOD_NAME()
{
// Call GetXml method which returns the result in the form of string
string result = GetXml("xmlfile.xml", "KEY2");
Debug.WriteLine(result);
}
private string GetXml(string filePath, string searchKey)
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNodeList nodes = doc.SelectSingleNode("//connections/production").ChildNodes;
string output = string.Empty;
foreach (XmlNode node in nodes)
{
if (node.Attributes["key"].Value == searchKey)
{
output = node.Attributes["data"].Value;
}
else
{
continue;
}
}
return output;
}
I'm trying to get the values from an XElement that I'm receiving from db notification.
The xml structure is like this:
<?xml version="1.0"?>
<root>
<inserted>
<row>
<CODI_AVERIA>22</CODI_AVERIA>
<NUMERO_LINIA>2</NUMERO_LINIA>
<DIA>2016-07-17T00:00:00</DIA>
<HORA>1899-12-30T10:26:15.790</HORA>
<CODI_USUARI>1</CODI_USUARI>
<ACCIO>0</ACCIO>
<CODI_PSEUDO>-1</CODI_PSEUDO>
</row>
</inserted>
</root>
And this is the method that I'm using to get the data, and it returns me a List that is empty.
static void getAccio(XElement xml)
{
try
{
xml.Descendants("deleted").Remove();
var items = xml.Elements("row").Select(n => new
{
Codi_averia = n.Element("CODI_AVERIA").Value,
Numero_linia = n.Element("NUMERO_LINIA)").Value,
Accio = n.Element("ACCIO").Value
}).ToList();
}
catch (Exception e)
{
Console.Write(e.Message);
}
}
I have tried to get the value of each field apart and it doesn't allow me to get them separetly as XElements.
Use .Descendants() instead of .Elements():
var items = xml.Descendants("row").Select(n => new
{
Codi_averia = n.Element("CODI_AVERIA").Value,
Numero_linia = n.Element("NUMERO_LINIA)").Value,
Accio = n.Element("ACCIO").Value
}).ToList();
.Elements finds only those elements that are direct descendents, i.e. immediate children. - And I assume that your XElement is the parent of the inserted section.
For difference between .Element and .Descendants see this question
If you don't want to find them in all inner elements too then do .Element("inserted").Elements("rows")
Your document doesn't have any root element with the name row. Instead, you need to select inserted first, and enumerate the row elements of inserted:
var xml = #"<inserted>
<row>
<CODI_AVERIA>21</CODI_AVERIA>
<NUMERO_LINIA>2</NUMERO_LINIA>
<DIA>2016-07-17T00:00:00</DIA>
<HORA>1899-12-30T10:26:15.790</HORA>
<CODI_USUARI>1</CODI_USUARI>
<ACCIO>0</ACCIO>
<CODI_PSEUDO>-1</CODI_PSEUDO>
</row>
</inserted>";
var xdoc = XDocument.Parse(xml);
var items = xdoc.Element("inserted").Elements("row").Select(n => new
{
Codi_averia = n.Element("CODI_AVERIA").Value,
Numero_linia = n.Element("NUMERO_LINIA").Value,
Accio = n.Element("ACCIO").Value
}).ToList();
In your sample code ("NUMERO_LINIA)") is wrong because of additionnal quote and parenthesis.
This works for me :
XDocument xd = XDocument.Load("XMLFile1.xml");
var lst = (from n in xd.Descendants("row")
select new
{
Codi_averia = n.Element("CODI_AVERIA").Value,
Numero_linia = n.Element("NUMERO_LINIA").Value,
Accio = n.Element("ACCIO").Value
}).ToList();
foreach (var item in lst)
Console.WriteLine(string.Format("{0}{1}{2}", item.Codi_averia, item.Numero_linia, item.Accio));
I have the following XML type file
<root>
<info version_id=... product_id=... account_id=...>
<CRM>
<result key=... value=...>
<result key=... value=...>
....
</CRM>
<result key=... value=....>
</info>
<info version_id=... product_id=... account_id=...>
<CRM>
<result key=... value=...>
<result key=... value=...>
....
</CRM>
<result key=... value=....>
</info>
</root>
I need for each "info" nodes to create the following list:
list(account+product, key, value)
And I must take only "key" and "value" information that are part of the CRM node.
So the close I want was with this code
string[] directoryXml = Directory.GetFiles(directory);
var listxmlresult = new List<XmlResultNode>();
foreach (var xmlfile in directoryXml)
{
var docxml = new XmlDocument();
docxml.Load(xmlfile);
XmlNodeList nodesInfo = docxml.SelectNodes("//info");
XmlNodeList nodesResult = docxml.SelectNodes("//info/CRM/result");
foreach (XmlNode info in nodesInfo)
{
string VersionId = info.Attributes["version_id"].Value;
string ProductId = info.Attributes["product_id"].Value;
string AccountId = info.Attributes["account_id"].Value;
string AccountProductId = AccountId + " : " + ProductId;
// verify that CRM node exist
if (docxml.SelectSingleNode("//info/CRM") == null)
{
//To do log info that CRM node is not available for the specific file
}
foreach (XmlNode result in nodesResult)
{
//To do verfiy value is empty
string Key = result.Attributes["key"].Value;
string Value = result.Attributes["value"].Value;
if (Value.Length != 0)
{
var listXmlResultTemp = new XmlResultNode(AccountProductId, Key, Value);
listxmlresult.Add(listXmlResultTemp);
}
}
}
}
But this code return list with all "key" "value" for each "accountproduct".
I cannot manage in my second loop to just read the current node.
I tried several xpath possibility but I cannot manage to take the current position with XmlNodeList.
Tks
It isn't very clear what you're trying to achieve as posted. I think you want to change the inner loop this way :
foreach (XmlNode result in info.SelectNodes("./CRM/result"))
{
string Key = result.Attributes["key"].Value;
string Value = result.Attributes["value"].Value;
.....
.....
}
I am trying to parse this XML document and match the guid with the link nodes. I have a GUI built in C# that will allow the user to input the guid, and I am trying to spit out the corresponding link node that corresponds with it.
For example. A user enters ID: 8385522 and the program would spit out:
http://once.www.example.com
The XML is as follows:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<title>
</title>
<link>
</link>
<description>
</description>
<language>
</language>
<lastBuildDate>
</lastBuildDate>
<item>
<title>Parsing Example</title>
<link>http://once.www.example.com</link>
<pubDate>Sun, 16 Sep 2012 02:44:02 </pubDate>
<guid>8385522</guid>
</item>
<item>
<title>Parsing Example 2</title>
<link>http://once.once.www.example2.com</link>
<pubDate>Sat, 29 Sep 2012 18:29:13 </pubDate>
<guid>8439191</guid>
</item>
</channel>
</rss>
I don't have any code written for the text box that the ID is being entered in. All I have in that field is:
void TextBox1TextChanged(object sender, EventArgs e)
{
}
Do I need put the function inside the text box field? Any help is appreciated.
Edit: Here is what I have so far:
private void button2_Click_1(object sender, EventArgs e)
{
Clipboard.Clear();
if (Directory.Exists(#"c:\text"))
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load(#"c:\text\text.xml");
XmlDocument lDoc = new XmlDocument();
lDoc.Load(#"c:\text\text.xml");
XmlNodeList ctextbox = xDoc.GetElementsByTagName("guid");
XmlNodeList link = lDoc.GetElementsByTagName("link");
I'm not sure exactly where the parsing function needs to be.
var links = from item in xdoc.Descendants("item")
where (int)item.Element("guid") == yourGuid
select (string)item.Element("link");
But comprehension syntax does not have keyword for selecting single value, thus you need to do links.SingleOrDefault(); to get your link.
Or you can do search with fluent API:
XDocument xdoc = XDocument.Load(#"c:\text\text.xml");
int guid = 8385522; // parse your guid from textbox
string link = xdoc.Descendants("item")
.Where(item => (int)item.Element("guid") == guid)
.Select(item => (string)item.Element("link"))
.SingleOrDefault();
If it is possible for searching some guid, which is not in file (looks like your case, because guid comes from textbox), then:
XDocument xdoc = XDocument.Load(#"c:\text\text.xml");
int guid = 8385525; // parse your guid from textbox
var links = from item in xdoc.Descendants("item")
where (int)item.Element("guid") == guid
select (string)item.Element("link");
string link = links.SingleOrDefault();
string link = GetLink(#"c:\text\text.xml", "8385522");
--
string GetLink(string xmlFile,string guid)
{
var xDoc = XDocument.Load(xmlFile);
var item = xDoc.Descendants("item")
.FirstOrDefault(x => (string)x.Element("guid") == guid);
if (item == null) return null;
return (string)item.Element("link");
}
I'm using this xml library, but you can use the XPath provided with .Net by including System.Linq.XPath I believe. (I can't check at the moment if that is 100% accurate).
XElement root = XElement.Load(file);
XElement guid = root.XPathElement("//guid[.={0}]", id);
XElement link = null;
if(null != guid)
link = guid.Parent.Element("link");
How can I get the value of a Node in a XDocument when don't has more childs ?
<Contacts>
<Company>
<Name>Testing</Name>
<ID>123</ID>
</Company>
</Contacts>
In this case, I wanna get the value of the <Name> and <ID> element, because don't has child elements in them.
I'm trying the follow
protected void LeXMLNode(HttpPostedFile file)
{
XmlReader rdr = XmlReader.Create(file.FileName);
XDocument doc2 = XDocument.Load(rdr);
foreach (var name in doc2.Root.DescendantNodes().OfType<XElement>().Select(x => x.Name).Distinct())
{
XElement Contact = (from xml2 in doc2.Descendants(name.ToString())
where xml2.Descendants(name.ToString()).Count() == 0
select xml2).FirstOrDefault();
string nome = name.ToString();
}
}
but without success, because my foreach pass in all Elements and I wanna get just the value of Elements that don't has childs.
document.Root.Elements("Company").Elements()
.Where(item => !item.HasElements).ToList();
See XElement.HasElements: http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.haselements.aspx