How to get all "cc" attribute values from below xml into a string array
<DD a="1" b="2" c="3">
<D aa="11" bb="22" cc="33"/>
<D aa="11" bb="22" cc="33"/>
<D aa="11" bb="22" cc="33"/>
</DD>
Cases I tried:
foreach (XmlNode xD in DD) {
XmlElement getFDD = (XmlElement)DD;
for (int x = 0; x < DD.ChildNodes.Count; x++)
{
XmlElement XmlFV = (XmlElement)DD.ChildNodes[x];
stringArr[x] = XmlFV.GetAttribute("CC");
}
}
And
for (int u = 0; u < DD.Count; u++)
{
getFDD = (XmlElement)DD[u].FirstChild;
XmlElement getFDD1 = (XmlElement)getFDD;
stringArr[u]=getFDD1.GetAttribute("cc");
}
I tried using foreach to loop through each node, i gave up trying that.
This should work for .Net 2.0
var doc = new XmlDocument();
doc.Load(fname);
List<string> list = new List<string>();
foreach(XmlNode node in doc.GetElementsByTagName("D"))
{
list.Add(node.Attributes["cc"].Value);
}
You can do it with LINQ2XML:
const string xml = #"
<DD a=""1"" b=""2"" c=""3"">
<D aa=""11"" bb=""22"" cc=""33""/>
<D aa=""11"" bb=""22"" cc=""33""/>
<D aa=""11"" bb=""22"" cc=""33""/>
</DD>";
var doc = XDocument.Parse(xml);
var res = doc.Element("DD") // Get the root element DD
.Elements("D") // Extract all sub-elements D
.Select(e => e.Attribute("cc").Value) // Extract attribute cc
.ToList();
Here is how to do it without LINQ2XML:
XmlReader r = XmlReader.Create(new StringReader(xml));
IList<string> res = new List<string>();
while (r.Read()) {
if (r.IsStartElement("D")) {
res.Add(r.GetAttribute("cc"));
}
}
Use Linq2Xml
XElement doc=XElement.Load(yourXmlPath);
String[] attr=doc.Elements("D")
.Select(x=>(String)x.Attribute("cc"))
.ToArray();
Related
xWaarde.Value is overriding with new values and flushing old values.
how to stored multiple values in Xelement.
private XElement[] AddCoordinatenList(XElement childElements)
{
XmlNode xmlCoordinatenNode = Utility.GetMappingValues(Constants.BMCoordinaten, ConnectionType.BM);
XmlNode xWaardeNode = Utility.GetMappingValues(Constants.BMXwaarde, ConnectionType.BM);
XmlNode yWaardeNode = Utility.GetMappingValues(Constants.BMYwaarde, ConnectionType.BM);
XmlNode CoordinateX = Utility.GetMappingValues(Constants.XCoordinate, ConnectionType.BM);
XmlNode CoordinateY = Utility.GetMappingValues(Constants.YCoordinate, ConnectionType.BM);
var coordinatenList = from document in childElements.DescendantsAndSelf() where document.Name.LocalName == xmlCoordinatenNode.Name select document;
List<XElement> xcoordinatenList = new List<XElement>();
XElement xWaarde = new XElement(CoordinateX.Name);
XElement yWaarde = new XElement(CoordinateY.Name);
if (coordinatenList.Count() > 0)
{
foreach (XElement element in coordinatenList.Descendants())
{
if (element.Name.LocalName == xWaardeNode.Name)
{
xWaarde.Value = element.Value;
}
if (element.Name.LocalName == yWaardeNode.Name)
{
yWaarde.Value = element.Value;
}
}
}
return xcoordinatenList.ToArray();
}
It's not possible. Use Attributes:
XAttribute attribute = new XAttribute("name1", <value>);
element.Add(attribute);
attribute = new XAttribute("name2", <value>);
element.Add(attribute);
You can also add a list of child elements or add all strings as one string, separated by a comma for instance.
I am getting output xml format in that can able to access appointment-nbr, but I am not able to eqid. How can I get slot-start,slot-end,eqid.
> <appointment-nbr>494</appointment-nbr> <slot
> slot-start="2018-07-16T12:31:00" slot-end="2018-07-16T13:00:00" />
> <appointment requires-xray="false" /> <container eqid="ASWU2705080" />
This is my code:
foreach (XmlNode node in appointmentsresponce){
XmlElement flightEle = (XmlElement)node;
XmlNodeList appointmentnbr = flightEle.GetElementsByTagName("appointment-nbr");
XmlNodeList containerNodeList = flightEle.GetElementsByTagName("container");
}
Try (I'm guessing a bit since you didn't post the full data):
foreach (XElement level1Element in XElement.Load(#"your_file.xml").Elements("appointment-nbr"))
{
foreach (XElement level2Element in level1Element.Elements("slot"))
{
Console.WriteLine(level1Element.Attribute("slot-start").Value);
}
}
Simple call GetAttribute("AttributeName") on your XmlElement
So:
var slotXml = appointmentsresponce.SelectSingleNode("//slot")
var startAttr = slotXml.GetAttribute("slot-start")
var endAttr = slotXml.GetAttribute("slot-end")
var containerXml = appointmentsresponce.SelectSingleNode("//container ")
var eqidAttr = containerXml .GetAttribute("eqid")
<?xml version="1.0" encoding="utf-8" ?>
<testcase>
<date>4/12/13</date>
<name>Mrinal</name>
<subject>xmlTest</subject>
</testcase>
I am trying to read the above xml using c#, But i get null exception in the try catch block can any body suggest the required change.
static void Main(string[] args)
{
XmlDocument xd = new XmlDocument();
xd.Load("C:/Users/mkumar/Documents/testcase.xml");
XmlNodeList nodelist = xd.SelectNodes("/testcase"); // get all <testcase> nodes
foreach (XmlNode node in nodelist) // for each <testcase> node
{
CommonLib.TestCase tc = new CommonLib.TestCase();
try
{
tc.name = node.Attributes.GetNamedItem("date").Value;
tc.date = node.Attributes.GetNamedItem("name").Value;
tc.sub = node.Attributes.GetNamedItem("subject").Value;
}
catch (Exception e)
{
MessageBox.Show("Error in reading XML", "xmlError", MessageBoxButtons.OK);
}
........
.....
The testcase element has no attributes. You should be looking to it's child nodes:
tc.name = node.SelectSingleNode("name").InnerText;
tc.date = node.SelectSingleNode("date").InnerText;
tc.sub = node.SelectSingleNode("subject").InnerText;
You might process all nodes like this:
var testCases = nodelist
.Cast<XmlNode>()
.Select(x => new CommonLib.TestCase()
{
name = x.SelectSingleNode("name").InnerText,
date = x.SelectSingleNode("date").InnerText,
sub = x.SelectSingleNode("subject").InnerText
})
.ToList();
You can use LINQ to XML to select all testcase elements from your xml and parse them to TestCase instances:
var xdoc = XDocument.Load("C:/Users/mkumar/Documents/testcase.xml");
var testCases = from tc in xdoc.Descendants("testcase")
select new CommonLib.TestCase {
date = (string)tc.Element("date"),
name = (string)tc.Element("name"),
sub= (string)tc.Element("subject")
};
BTW you have only one testcase element currently, which is root of XML file. So, you can do instead:
var tc = XElement.Load("C:/Users/mkumar/Documents/testcase.xml");
var testCase = new CommonLib.TestCase {
date = (string)tc.Element("date"),
name = (string)tc.Element("name"),
sub= (string)tc.Element("subject")
};
private static void Main(string[] args)
{
XmlDocument xd = new XmlDocument();
xd.Load("C:\\test1.xml");
XmlNodeList nodelist = xd.SelectNodes("/testcase"); // get all <testcase> nodes
foreach (XmlNode node in nodelist) // for each <testcase> node
{
try
{
var name = node.SelectSingleNode("date").InnerText;
var date = node.Attributes.GetNamedItem("name").Value;
var sub = node.Attributes.GetNamedItem("subject").Value;
}
catch (Exception e)
{
MessageBox.Show("Error in reading XML", "xmlError", MessageBoxButtons.OK);
}
}
This will work I have test it #Alex correct answer
You are trying to read attributes whereas date, name and subject are not attributes. They are subnodes.
your code should be like this
XmlDocument xd = new XmlDocument();
xd.Load("test.xml");
XmlNodeList nodelist = xd.SelectNodes("/testcase"); // get all <testcase> nodes
foreach (XmlNode node in nodelist) // for each <testcase> node
{
try
{
string name = node.SelectSingleNode("name").InnerText;
string date = node.SelectSingleNode("date").InnerText;
string sub = node.SelectSingleNode("subject").InnerText;
}
catch (Exception ex)
{
MessageBox.Show("Error in reading XML", "xmlError", MessageBoxButtons.OK);
}
}
Your Xml do not contain Attributes. date, name and subject - it's Child Nodes of the testcase Node.
Try this:
...
tc.name = node["name"].InnerText;
...
or this:
...
tc.name = node.SelectSingleNode("name").InnerText;
...
I have the following piece of code
XmlDocument docu = new XmlDocument();
docu.Load(file);
XmlNodeList lst = docu.GetElementsByTagName("name");
foreach (XmlNode n in lst)
{
string text = n.InnerText;
var types = doc.Element("program").Element("program-function").Element("function").Descendants("type").Where(x => x.Value == text).Select(c => c.Value).ToArray();
}
my xml is as follows
<program>
<program-function>
<function>
<name>add</name>
<return-type>double</return-type>
<params>
<type>double</type>
<type-value>a</type-value>
<type>double</type>
<type-value>b</type-value>
<type>string</type>
<type-value>c</type-value>
</params>
<body> return a + b + c; </body>
</function>
<function>
<name>test</name>
<return-type>int</return-type>
<params>
<type>double</type>
<type-value>a</type-value>
<type>double</type>
<type-value>b</type-value>
</params>
<body> return a + b; </body>
</function>
</program-function>
</program>
i need to be able to get the number of <type> for each <name>
result for add should be 3 = types.count() = 3
result for test should be 2 = types.count() = 2
any advice?
EDIT : If i want to retrieve each value inside types? ie. add should contain a,b,c and test should contain a,b. Would love to store it in an array for easier retrieval
How about using Linq to Xml
var xDoc = XDocument.Parse(xml);
var functions = xDoc.Descendants("function")
.Select(f => new
{
Name = f.Element("name").Value,
Types = f.Descendants("type").Select(t=>t.Value).ToList(),
//Types = f.Descendants("type").Count()
TypeValues = f.Descendants("type-value").Select(t=>t.Value).ToList()
})
.ToList();
Try this:
XDocument doc = XDocument.Load(your file);
var vals = doc.Element("program").Element("program-function").Elements("function");
var result = vals.Select(i =>
new { name = i.Element("name"),
count = i.Elements("type").Count() }
Currently I have the following code:
XmlDocument xDoc = new XmlDocument();
xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");
XmlNodeList tweets = xDoc.GetElementsByTagName("text");
foreach (int i in tweets)
{
if (tweets[i].InnerText.Length > 0)
{
MessageBox.Show(tweets[i].InnerText);
}
}
Which doesn't work, it gives me System.InvalidCastException on the foreach line.
The following code works perfectly (no foreach, the i is replaced with a zero):
XmlDocument xDoc = new XmlDocument();
xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");
XmlNodeList tweets = xDoc.GetElementsByTagName("text");
if (tweets[0].InnerText.Length > 0)
{
MessageBox.Show(tweets[0].InnerText);
}
I know that there is already a marked answer, but you can do it like you did in your first try, you just need to replace the int with XmlNode
XmlDocument xDoc = new XmlDocument();
xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");
XmlNodeList tweets = xDoc.GetElementsByTagName("text");
foreach (XmlNode i in tweets)
{
if (i.InnerText.Length > 0)
{
MessageBox.Show(i.InnerText);
}
}
tweets is a node list. I think that what you're trying to do is this:
XmlDocument xDoc = new XmlDocument();
xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");
XmlNodeList tweets = xDoc.GetElementsByTagName("text");
for (int i = 0; i < tweets.Count; i++)
{
if (tweets[i].InnerText.Length > 0)
{
MessageBox.Show(tweets[i].InnerText);
}
}
It is not of Int type, That is the reason you are getting a casting exception. You can either replace int with the appropriate type or simply make use of type inference (implicitly typed variables) to handle this. Here i am using typeinference.by saying type as var, The compiler will understand it is of type of the iterator variable in tweets collection
foreach (var i in tweets)
{
if (i!=null)
{
string tweet= (((System.Xml.XmlElement)(i))).InnerText;
MessageBox.Show(tweet);
}
}
EDIT : With the Wonderful LINQtoXML, Your code can be rewritten like this.
string url = "http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter";
XElement elm = XElement.Load(url);
if (elm != null)
{
foreach (var status in elm.Elements("status"))
{
string tweet = status.Element("text").Value;
MessageBox.Show(ss);
}
}
All the answers seem to be a bit outdated Imperative examples so I will add a declarative one. This is not doing what the OP wanted but I'm sure you'll get the point.
public static List<System.Xml.XmlNode> toList(System.Xml.XmlNodeList nodelist){
List<System.Xml.XmlNode> nodes = new List<System.Xml.XmlNode>();
foreach (System.Xml.XmlNode node in nodelist)
{
nodes.Add(node);
}
return nodes;
}
public static ReadMeObject setXml(ReadMeObject readmeObject){
readmeObject.xmlDocument = new System.Xml.XmlDocument();
readmeObject.xmlDocument.LoadXml("<body>"+readmeObject.htmlStringContent+"</body>");
System.Xml.XmlNodeList images = readmeObject.xmlDocument.SelectNodes("//img");
Array.ForEach(
Functions.toList( images )
.Where((image) => image.Attributes != null)
.Where((image) => image.Attributes["src"] != null)
.Where((image) => image.Attributes["src"].Value != "")
.ToArray()
, (image) => {
Console.WriteLine(image.Attributes["src"].Value);
}
);
return readmeObject;
}
foreach (XmlNode node in tweets)
{
if (tweets[i].InnerText.Length > 0)
{
MessageBox.Show(tweets[node].InnerText);
}
}
I've changed the 'I', which you cannot use, to XmlNode, which selects a single line of your list.
You can loop through the Collection with .GetEnumerator()
this code is taken Microsoft Documentation :
XmlNodeList elemList = root.GetElementsByTagName("title");
IEnumerator ienum = elemList.GetEnumerator();
while (ienum.MoveNext()) {
XmlNode title = (XmlNode) ienum.Current;
Console.WriteLine(title.InnerText);
}
Use this simple extension method to iterate through XmlNodeList:
public static void ForEachXml<TXmlNode>(this XmlNodeList nodeList, Action<TXmlNode> action)
{
foreach (TXmlNode node in nodeList) action(node);
}
Method Call:
xDoc.GetElementsByTagName("text").ForEachXML<XmlNode>(tweet =>
{
if (tweet.InnerText.Length > 0)
MessageBox.Show(tweet.InnerText);
});