XML to string (C#) - c#

I have a XML loaded from a URL like this:
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
try
{
string reply = client.DownloadString("http://Example.com/somefile.xml");
label1.Text = reply;
}
catch
{
label1.Text = "FAILED";
}
That XML belongs to a RSS Feed. I want that label1.Text shows just the titles of that XML. How can I achieve that?
Example of label1.Text
This is my first title - This is my 2nd title - And this is my last title

You can load your XML into an XmlDocument and then use XPath to Get the value of each node you're targeting.
XmlDocument doc = new XmlDocument();
doc.LoadXml(reply);
XmlNodeList nodes = doc.SelectNodes("//NodeToSelect");
foreach (XmlNode node in nodes)
{
//If the value you want is the content of the node
label1.Text = node.InnerText;
//If the value you want is an attribute of the node
label1.Text = node.Attributes["AttibuteName"].Value;
}
If you are not familiar with XPath you can always check here :
http://www.w3schools.com/xpath/xpath_syntax.asp

var xml= XElement.Parse(reply);
label1.Text = string.Join(Environment.NewLine, xml
.Descendants()
.Where (x => !string.IsNullOrEmpty(x.Value))
.Select(x=> string.Format("{0}: {1}", x.Name, x.Value))
.ToArray());

You probably need to parse the RSS XML manually to get the title. Here is some sample code for your reference:
private static List<FeedsItem> ParseFeeds(string feedsXml)
{
XDocument xDoc = XDocument.Parse(feedsXml);
XNamespace xmlns = "http://www.w3.org/2005/Atom";
var items = from entry in xDoc.Descendants(xmlns + "entry")
select new FeedsItem
{
Id = (string)entry.Element(xmlns + "id").Value,
Title = (string)entry.Element(xmlns + "title").Value,
AlternateLink = (string)entry.Descendants(xmlns + "link").Where(link => link.Attribute("rel").Value == "alternate").First().Attribute("href").Value
};
Console.WriteLine("Count = {0}", items.Count());
foreach(var i in items)
{
Console.WriteLine(i);
}
return null;
}

Related

XmlDocument sort nodes by the inner text value of a child

i want to sort the nodes called ImageInfo by the number in the pos node because i have buttons that change the position up or down and i need to sort the ImageInfo node in the correct order when the pos has changed.
i apologise ahead for not having any c# code but i assure you that i have tried so many different things and im in need of help.
here is my xml:
<?xml version="1.0" encoding="utf-8"?>
<MplAndSiImages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MplImages>
<ImageInfo>
<pos>1</pos>
<Name>1.png</Name>
<ParentObjectId>b66a23a8-6268-e611-80e2-c4346bad02e8</ParentObjectId>
<Url>http://localhost:8080/b66a23a8-6268-e611-80e2-c4346bad02e8/1.png</Url>
</ImageInfo>
<ImageInfo>
<pos>2</pos>
<Name>2.png</Name>
<ParentObjectId>b66a23a8-6268-e611-80e2-c4346bad02e8</ParentObjectId>
<Url>http://localhost:8080/b66a23a8-6268-e611-80e2-c4346bad02e8/2.png</Url>
</ImageInfo>
<ImageInfo>
<pos>3</pos>
<Name>3.png</Name>
<ParentObjectId>b66a23a8-6268-e611-80e2-c4346bad02e8</ParentObjectId>
<Url>http://localhost:8080/b66a23a8-6268-e611-80e2-c4346bad02e8/3.png</Url>
</ImageInfo>
</MplImages>
<SiImages />
</MplAndSiImages>
here is my c# code:
it is called on the click of an action link button and i need it to change the poition to 1 less to move it up in the list and i have the number change but the xml need s to be sorted so it has the ImageInfo nodes in the correct order.
public ActionResult MoveUp(string name, string id)
{
var pathConfig = WebConfigurationManager.AppSettings["ProductImageFolderPath"];
var url = pathConfig + id + "\\" + "ModelConfig.xml";
XmlDocument doc = new XmlDocument();
doc.Load(url);
XmlNode root = doc.DocumentElement;
XmlNode upNode = root.SelectSingleNode("/MplAndSiImages/MplImages/ImageInfo[Name/text() = '" + name + "']/pos");
string upNodeValue = upNode.InnerText;
int upNodeInt = Int32.Parse(upNodeValue);
upNodeInt = upNodeInt - 1;
var upNodeString = upNodeInt.ToString();
upNode.InnerText = upNodeString;
XmlNode downNode = root.SelectSingleNode("/MplAndSiImages/MplImages/ImageInfo/pos[text() = '" + upNodeString + "']");
string downNodeValue = downNode.InnerText;
int downNodeInt = Int32.Parse(downNodeValue);
downNodeInt = downNodeInt + 1;
var downNodeString = downNodeInt.ToString();
downNode.InnerText = downNodeString;
Func<string, int> ParseIntOrDefault = (string input) =>
{
int output;
int.TryParse(input, out output);
return output;
};
var result = doc.SelectNodes("MplAndSiImages/MplImages/*")
.Cast<XmlNode>()
.OrderBy(element => element.SelectSingleNode("pos").InnerText)
.ToList();
doc.Save(url);
return RedirectToAction("UploadAnImage", new { id = id });
}
I have seen this and tried it but is there any way of doing this with xmldocument:
XElement root = XElement.Load(xmlfile);
var orderedtabs = root.Elements("Tab")
.OrderBy(xtab => (int)xtab.Element("Order"))
.ToArray();
root.RemoveAll();
foreach(XElement tab in orderedtabs)
root.Add(tab);
root.Save(xmlfile);
I am ordering the images to display on a web page.
and when the move up button is pressed the image will be moved up in the list and swap places with the image above it.
Using linq to xml you can:
var result = XDocument.Load("data.xml")
.Descendants("ImageInfo")
.OrderBy(element => element.Element("pos")?.Value)
.ToList();
And in order to order it by the int value of it you can:
Func<string,int> ParseIntOrDefault = (string input) =>
{
int output;
int.TryParse(input, out output);
return output;
};
var result = XDocument.Load("data.xml")
.Descendants("ImageInfo")
.OrderBy(element => ParseIntOrDefault(element.Element("pos")?.Value))
.ToList();
Using XmlDocument to read the xml you can:
var doc = new XmlDocument();
doc.Load("data.xml");
var result = doc.SelectNodes("MplAndSiImages/MplImages/*")
.Cast<XmlNode>()
.OrderBy(element => element.SelectSingleNode("pos").InnerText)
.ToList();
Here too you can use the ParseIntOrDefault from above

Not able to read XML string in C#

I have created a XML string and Looping that to get value. But its not entering in foreach loop. But in my other code same loop code is working.
my code is :
XML string:
<SuggestedReadings>
<Suggestion Text="Customer Centricity" Link="http://wdp.wharton.upenn.edu/book/customer-centricity/?utm_source=Coursera&utm_medium=Web&utm_campaign=custcent" SuggBy="Pete Fader�s" />
<Suggestion Text="Global Brand Power" Link="http://wdp.wharton.upenn.edu/books/global-brand-power/?utm_source=Coursera&utm_medium=Web&utm_campaign=glbrpower" SuggBy="Barbara Kahn�s" />
</SuggestedReadings>
Code Is:
string str = CD.SRList.Replace("&", "&");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(str);
XmlNode SuggestionListNode = xmlDoc.SelectSingleNode("/SuggestedReadings/Suggestion");
foreach (XmlNode node in SuggestionListNode)
{
COURSESUGGESTEDREADING CSR = new COURSESUGGESTEDREADING();
var s = db.COURSESUGGESTEDREADINGS.OrderByDescending(o => o.SRID);
CSR.SRID = (s == null ? 0 : s.FirstOrDefault().SRID) + 1;
CSR.COURSEID = LibId;
CSR.TEXT = node.Attributes.GetNamedItem("Text").Value;
CSR.LINK = node.Attributes.GetNamedItem("Link").Value; ;
CSR.SUGBY = node.Attributes.GetNamedItem("SuggBy").Value; ;
CSR.ACTIVEFLAG = "Y";
CSR.CREATEDBY = CD.CreatedBy;
CSR.CREATEDDATE = DateTime.Now;
db.COURSESUGGESTEDREADINGS.Add(CSR);
}
You should use SelectNodes, not SelectSingleNode, since you are trying to get multiple rows out of the XML document.
Use this:
XmlNodeList SuggestionListNode = xmlDoc.SelectNodes("//Suggestion");
foreach (XmlNode node in SuggestionListNode)
{
}
You can try this.
XDocument xdoc = XDocument.Load("data.xml");
var xmlData = from lv1 in xdoc.Descendants("Suggestion")
select new {
Text = lv1.Attribute("Text").Value,
Link = lv1.Attribute("Link").Value,
SuggBy = lv1.Attribute("SuggBy").Value
};
foreach (var item in xmlData){
// your logic here
}

Loop through XML with XmlDocument

I'm new to using Linq and XMLDocument.
I have a simple XML file and I want to loop through all of the elements and print the tag and value. I don't want to use the XML Tags when looping through. this is what I have so far.
XML file:
<?xml version="1.0" encoding="UTF-8"?>
<Step1>One
<Step2>Two
<Step3>Three
<Step4>Four
</Step4>
</Step3>
</Step2>
</Step1>
C# Code
private void StartIt()
{
System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
xd.Load(#"C:\Projects\GetXML\testLayers.xml");
XmlNodeList nl = xd.SelectNodes("Layer1");
foreach (XmlNode xnode in nl)
{
Console.WriteLine(xnode.Name + " = " + xnode.InnerText); // + " " + xnode.InnerXml);
}
}
Results:
Step1 = One
Two
Three
Four
What I want:
Step1 = One
Step2 = Two
Step3 = Three
Step4 = Four
Any suggestions?
With a little help of Linq,
XmlDocument doc = new XmlDocument();
doc.Load(fname);
var nodes = doc.SelectNodes("//*[text()]")
.Cast<XmlNode>()
.Select(n => new {
Name= n.Name,
Value = n.SelectSingleNode("text()").Value
})
.ToList();
// System.Xml.XmlDocument version
XmlDocument xd = new XmlDocument();
xd.Load(#"C:\Projects\GetXML\testLayers.xml");
foreach (XmlElement step in xd.SelectNodes("//*"))
{
Console.WriteLine("{0} = {1}", step.Name,
step.SelectSingleNode("text()").Value);
}
// System.Xml.Linq.XDocument version
XDocument xdLinq = XDocument.Load(#"C:\Projects\GetXML\testLayers.xml");
foreach (XElement step in xdLinq.XPathSelectElements("//*"))
{
Console.WriteLine("{0} = {1}", step.Name,
step.Nodes().Where(n => n.NodeType == XmlNodeType.Text).FirstOrDefault());
}
You can do the same using LINQ to XML and XDocument class:
var xDoc = XDocument.Load("Input.txt");
foreach (var e in xDoc.Descendants())
{
Console.WriteLine("{0} = {1}", e.Name, e.Nodes().OfType<XText>().First().Value.Trim());
}

How to update the XMLDocument using c#?

I want to update the xml document and i need to return the updated xml in string. I am trying like below. when i save the document it expects the file name. but i dont want to save this as file. i just want to get the updated xml in string.
string OldXml = #"<Root>
<Childs>
<first>this is first</first>
<second>this is second </second>
</Childs
</Root>";
XmlDocument NewXml = new XmlDocument();
NewXml.LoadXml(OldXml );
XmlNode root = NewXml.DocumentElement;
XmlNodeList allnodes = root.SelectNodes("*");
foreach (XmlNode eachnode in allnodes)
{
if (eachnode.Name == "first")
{
eachnode.InnerText = "1";
}
}
NewXml.Save();
string newxml = NewXml.OuterXml;
You don't need to call Save method because string is immutable, your problem is in root.SelectNodes("*"), it just get child nodes, not all level of nodes. You need to go one more level:
foreach (XmlNode eachnode in allnodes)
{
var firstNode = eachnode.ChildNodes.Cast<XmlNode>()
.SingleOrDefault(node => node.Name == "first");
if (firstNode != null)
{
firstNode.InnerText = "1";
}
}
string newxml = NewXml.OuterXml;
It would be strongly recommended using LINQ to XML, it's simpler:
var xDoc = XDocument.Parse(OldXml);
foreach (var element in xDoc.Descendants("first"))
element.SetValue(1);
string newXml = xDoc.ToString();
Your iteration never reaches a node called "first". Else it would work fine without saving the NewXml.
You could however use a XElement and iterate over all descendants.
string OldXml = #"<Root>
<Childs>
<first>this is first</first>
<second>this is second </second>
</Childs>
</Root>";
var NewXml = XElement.Parse(OldXml);
foreach (var node in NewXml.Descendants())
{
if (node.Name.LocalName == "first")
{
node.Value = "1";
}
}
var reader = NewXml.CreateReader();
reader.MoveToContent();
string newxml = reader.ReadInnerXml();

Find all the child node of specific value in C#

<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>
that is my XML file named simpan. I have two button. next and previous. What i want to do is, all the info will shows off on the TextBox when the user click the button. The searching node will be based on the pid.
Next button will adding 1 value of pid (let's say pid=2) and it will search on the node that have the same value of pid=2. it also will show the name for the pid=2. (showing name=abc)
Same goes to the previous button where it will reduce 1value of pid (pid=1).
Does anybody knows how to do this?
//-------------EDIT------------------
thanks to L.B, im trying to use his code. however i got an error.
is my implementation of code correct?
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Parse("C:\\Users\\HDAdmin\\Documents\\Fatty\\SliceEngine\\SliceEngine\\bin\\Debug\\simpan.xml");
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("PatientID") == pid)
.Value;
textETA.Text = name;
////////////////////
}
int pid = 2;
XDocument xDoc = XDocument.Parse(xml); //Load
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("pid") == pid)
.Element("name")
.Value;
You can use the following XPath to list all Myself tags, then look for what you want using a simple Linq command:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "file1.xml");
var resNodes = xmlDoc.SelectNodes("//myself");
XmlNode res = null;
var val = textBox1.Text;
var item = from XmlNode x in resNodes
select x;
foreach (var nodP in item) {
foreach (XmlNode nod in nodP.ChildNodes) {
if (nod.InnerText == val) {
res = nodP;
}
}
}
if (res == null)
// not found!
;
else
// show the result
;
Call me old fashioned but you could use an XPath, for example:
string xml =
#"<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>";
using System.Xml;
....
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
// Replace "2" in the string below with the desired pid
XmlNode xmlNode =
xmlDocument.DocumentElement.SelectSingleNode("myself/name[../pid=2]");
// xmlNode contains the <name>efg</name> XmlElement. For example:
string name = xmlNode.Value;
If it can match multiple nodes, for example there could be multiple <myself> elements with a child element <pid> set to 2, use the following instead:
foreach(XmlNode xmlNode in
xmlDocument.DocumentElement.SelectNodes("myself/name[../pid=2]"))
{
// xmlNode contains the matching <name> element
}
In both cases, the value can be extracted from the XmlNode using the Value property.
public class simpman
{
private static XElement root = XElement.Load("Simpman.xml");
public static string GetItem(int index)
{
XElement item =
(from element in root.Elements("myself")
where (int)element.Element("pid") == index
select element.Element("name")).SingleOrDefault();
return item != null ? item.Value : "Please check the Index";
}
}
Initialize a static itemIndex to 1 and use it further like itemIndex++ (for Next) and itemIndex-- (for Prev).
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Load(#"C:\Users\HDAdmin\Documents\Fatty\SliceEngine\SliceEngine\bin\Debug\simpan.xml");
var name = xDoc.Root
.Descendants("myself")
.FirstOrDefault(e => e.Element("pid")
.Value
.Equals(pid.ToString(CultureInfo.InvariantCulture)))
.Element("name")
.Value;
textETA.Text = name;
}
XmlDocument doc = new XmlDocument();
FileStream fs = new FileStream(rootXMLPath, FileMode.Open, FileAccess.Read);
doc.Load(fs);
XmlNode node = doc.DocumentElement;
nodeName = "/main/myself";
var child1 = node.SelectSingleNode(nodeName).ChildNodes[0].FirstChild.InnerXml;
var child2 = node.SelectSingleNode(nodeName).ChildNodes[0].LastChild.InnerXml;
var child3 = node.SelectSingleNode(nodeName).ChildNodes[1].FirstChild.InnerXml;
var child4 = node.SelectSingleNode(nodeName).ChildNodes[1].LastChild.InnerXml;

Categories

Resources