How to Read XML element with namespace value - c#

I am facing problem in fetching xml element value if it is having name space. please help me what is the problem here. My xml string is below
<PurchaseOrder xmlns:aw="http://www.adventure-works.com"> <aw:ShippingAddress> <aw:Name>John</aw:Name> <aw:Street>123 Main St.</aw:Street> <aw:City>Seattle</aw:City> <aw:State>WA</aw:State> <aw:Zip>98113</aw:Zip> <aw:Country>USA</aw:Country> </aw:ShippingAddress> <aw:ShippingAddress> <aw:Name>Chris Preston</aw:Name> <aw:Street>123 Robin St.</aw:Street> <aw:City>Newyork</aw:City> <aw:State>TU</aw:State> <aw:Zip>98113</aw:Zip> <aw:Country>USA</aw:Country> </aw:ShippingAddress> <aw:ShippingAddress> <aw:Name>Charlis</aw:Name> <aw:Street>53 Jacob St.</aw:Street> <aw:City>California</aw:City> <aw:State>DOWNTOWN</aw:State> <aw:Zip>98111</aw:Zip> <aw:Country>USA</aw:Country> </aw:ShippingAddress> </aw:PurchaseOrder>
my code is below
XDocument doc = XDocument.Load("PurchaseOrder.xml");
List<PurchaseOrder> listWO = new List<PurchaseOrder>();
foreach (XElement el in doc.Root.Elements())
{
if ( el.Elements().Count() > 0)
{
PurchaseOrder po = new PurchaseOrder
{
Name = el.Elements("aw:Name").First().Value,
City = el.Elements("aw:City").First().Value,
Country = el.Elements("aw:Country").First().Value
};
listPO.Add(po):
}
}
Here i am not getting the value of each "ShippingAddress" wise.

See changes below :
XDocument doc = XDocument.Load("PurchaseOrder.xml");
XNamespace awNs = doc.Root.GetNamespaceOfPrefix("aw");
List<PurchaseOrder> listWO = new List<PurchaseOrder>();
foreach (XElement el in doc.Root.Elements())
{
if ( el.Elements().Count() > 0)
{
PurchaseOrder po = new PurchaseOrder
{
Name = el.Elements(awNs + "Name").First().Value,
City = el.Elements(awNs + "City").First().Value,
Country = el.Elements(awNs + "Country").First().Value
};
listPO.Add(po):
}
}

Related

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
}

Parsing XML - Value out of range

I have a problem, I am trying to list all my tfs projects and I am having this exception:
Value does not fall within the expected range.
Here is my method
public async Task<XElement> Deserialize()
{
string xml = "https://tfsodata.visualstudio.com/DefaultCollection/Projects('xxxx')/WorkItems";
var feed = await this.GetAsync(PROJECTS_PATH);
var x = feed.Items.ToString();
XElement dataTfs = new XElement(x);
foreach(var tfsdata in feed.Items)
{
var xDoc = XDocument.Parse(tfsdata.Content.Text);
IEnumerable<XElement> elem = xDoc.Elements();
XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
var data = from query in xDoc.Descendants(m + "properties")
select new TfsEntities.Models.TfsEntities.properties
{
Title = (string)query.Element(d + "Title"),
State = (string)query.Element(d + "State"),
Reason = (string)query.Element(d + "Reason")
};
dataTfs.Add(data.ToList());
}
return (XElement)dataTfs;
}
Does anyone know how to fix this problem please?
Thank you

Get data from XML in simple way

I am using the following code to get data from the OData XML and its works ,
but I am not sure that I fully understand it so maybe there is a way to write it in simple way?
what i need is to get the property value which is in the first loop value = 0001 and text = approve and in the
second value = 0002 text = reject
The code
XNamespace dns = "http://schemas.microsoft.com/ado/2007/08/dataservices";
if (response.StatusCode == HttpStatusCode.OK)
{
string decisionOptions = ReadResponse(response);
XDocument document = XDocument.Parse(decisionOptions);
foreach (XElement element in document.Element(dns + "DecisionOptions").Elements(dns + "element"))
{
PropertyKeyRef decisionOption = new PropertyKeyRef();
decisionOption.PropertyValue = element.Element(dns + "DecisionKey").Value;
decisionOption.PropertyName = element.Element(dns + "DecisionText").Value;
dat.Add(decisionOption);
}
}
the XML
<?xml version="1.0" encoding="utf-8" ?>
- <d:DecisionOptions xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
- <d:element m:type="TAS.DecisionOption">
<d:InstanceID>007</d:InstanceID>
<d:DecisionKey>0001</d:DecisionKey>
<d:DecisionText>Approve</d:DecisionText>
<d:CommentMandatory>false</d:CommentMandatory>
<d:Nature>POSITIVE</d:Nature>
</d:element>
- <d:element m:type="TAS.DecisionOption">
<d:InstanceID>007</d:InstanceID>
<d:DecisionKey>0002</d:DecisionKey>
<d:DecisionText>Reject</d:DecisionText>
<d:CommentMandatory>true</d:CommentMandatory>
<d:Nature>NEGATIVE</d:Nature>
</d:element>
</d:DecisionOptions>
here how can do it in simple way using LINQ
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
XDocument xdoc = XDocument.Load("test.xml");
XNamespace dns = "http://schemas.microsoft.com/ado/2007/08/dataservices";
//in xml every element should have it's namespace for this reason I have to concatenate namespace with the name of element
var elementsRes = xdoc.Root.Elements(dns+"element").Select((elt) => new PropertyKeyRef { PropertyName = elt.Element(dns+"DecisionKey").Value.ToString(),PropertyValue = elt.Element(dns+"DecisionText").Value.ToString() }).ToList();
foreach (var item in elementsRes)
{
//your code for the result
}
}
}
public class PropertyKeyRef
{
public string PropertyName
{ get; set; }
public string PropertyValue
{ get; set; }
}
}
You have already achieved it in simplest way. Little bit of LINQ might improve readability (get away with foreach loop) but it's just syntactic sugar of what you have written.
XNamespace dns = "http://schemas.microsoft.com/ado/2007/08/dataservices";
XDocument document = XDocument.Load("database.xml");
PropertyKeyRef decisionOption = new PropertyKeyRef();
decisionOption.PropertyValue = document.Descendants(dns + "DecisionKey")
.Select(node => node.Value).First();
decisionOption.PropertyName = document.Descendants(dns + "DecisionText")
.Select(node => node.Value).First();
dat.Add(decisionOption);

Get actual Column name from XML

I have a problem with this XML. In our system we are using XML from DataSet (ds.GetXml()) and send it to our Silverlight application as a string. From there we read the XML with the following:
StringReader stream = new StringReader(XmlData);
XmlReader reader = XmlReader.Create(stream);
XDocument myDoc = new XDocument();
myDoc = XDocument.Load(reader);
The problem: Some times column names are changed, example: If a column name starts with a numeric number then it will convert it.
"_x0033_column" original column name was "3column"
Is it possible to get the original column name from the XML?
The XML
<NewDataSet>
<Table>
<CheckboxCol>0</CheckboxCol>
<Kunde>1</Kunde>
<Ort_x0020_Postfach />
<erfasst_x0020_von>MasterMind</erfasst_x0020_von>
<Buchhaltungsnummer>1</Buchhaltungsnummer>
<Kreditlimit>0.0000</Kreditlimit>
<_x0033_STT_Inaktiv>Nein</_x0033_STT_Inaktiv>
<_x0033_STT_Status>Interessent</_x0033_STT_Status>
<Zahlungsbedingungen>10 : 10 Tage Netto</Zahlungsbedingungen>
</Table>
<Table>
<CheckboxCol>0</CheckboxCol>
<Kunde>3</Kunde>
<Ort_x0020_Postfach />
<erfasst_x0020_von>MasterMind</erfasst_x0020_von>
<Buchhaltungsnummer>3</Buchhaltungsnummer>
<Kreditlimit>0.0000</Kreditlimit>
<_x0033_STT_Inaktiv>Nein</_x0033_STT_Inaktiv>
<_x0033_STT_Status>Kunde</_x0033_STT_Status>
<Zahlungsbedingungen>10 : 10 Tage Netto</Zahlungsbedingungen>
</Table>
<NewDataSet>
My current Code
public SLDataTable(string XmlData, Dictionary<string, string> ColumnDict)
{
ColumnDefination = ColumnDict;
foreach (var Item in ColumnDefination)
{
Columns.Add(new SLDataColumn() { ColumnName = Item.Key.ToString().Trim(), DataType = GetNullableType(GetColumnType(Item.Value.ToString())) });
}
StringReader stream = new StringReader(XmlData);
XmlReader reader = XmlReader.Create(stream);
XDocument myDoc = new XDocument();
myDoc = XDocument.Parse(XmlData);
if (myDoc != null && myDoc.Elements().Count() > 0 && myDoc.Element("NewDataSet").Elements().Count() > 0)
{
int columnCount = myDoc.Element("NewDataSet").Element("Table").Elements().Count();
int rowCount = myDoc.Element("NewDataSet").Elements().Count();
string ElmentColumnName = string.Empty;
foreach (XElement element in myDoc.Element("NewDataSet").Elements())
{
var row = new SLDataRow(this);
foreach (XElement ele in element.Elements())
{
ElmentColumnName = ele.Name.ToString().Replace("_x0020_", " ").Replace("_x0028_", " (").Replace("_x0029_", ") ");
row[ElmentColumnName] = ConvertValue(ElmentColumnName, ele.Value);
}
Rows.Add(row);
}
}
}

Doing CRUD on XML using id attributes in C# ASP.NET

I'm a LAMP guy and ended up working this small news module for an asp.net site, which I am having some difficulty with. I basically am adding and deleting elements via AJAX based on the id. Before, I had it working based on the the index of a set of elements, but would have issues deleting, since the index would change in the xml file and not on the page (since I am using ajax).
Here is the rundown
news.xml
<?xml version="1.0" encoding="utf-8"?>
<news>
<article id="1">
<title>Red Shield Environmental implements the PARCSuite system</title>
<story>Add stuff here</story>
</article>
<article id="2">
<title>Catalyst Paper selects PARCSuite for its Mill-Wide Process...</title>
<story>Add stuff here</story>
</article>
<article id="3">
<title>Weyerhaeuser uses Capstone Technology to provide Control...</title>
<story>Add stuff here</story>
</article>
</news>
Page sending del request:
<script type="text/javascript">
$(document).ready(function () {
$('.del').click(function () {
var obj = $(this);
var id = obj.attr('rel');
$.post('add-news-item.aspx',
{ id: id },
function () {
obj.parent().next().remove();
obj.parent().remove();
}
);
});
});
</script>
<a class="del" rel="1">...</a>
<a class="del" rel="1">...</a>
<a class="del" rel="1">...</a>
My functions
protected void addEntry(string title, string story)
{
XmlDocument news = new XmlDocument();
news.Load(Server.MapPath("../news.xml"));
XmlAttributeCollection ids = news.Attributes;
//Create a new node
XmlElement newelement = news.CreateElement("article");
XmlElement xmlTitle = news.CreateElement("title");
XmlElement xmlStory = news.CreateElement("story");
XmlAttribute id = ids[0];
int myId = int.Parse(id.Value + 1);
id.Value = ""+myId;
newelement.SetAttributeNode(id);
xmlTitle.InnerText = this.TitleBox.Text.Trim();
xmlStory.InnerText = this.StoryBox.Text.Trim();
newelement.AppendChild(xmlTitle);
newelement.AppendChild(xmlStory);
news.DocumentElement.AppendChild(newelement);
news.Save(Server.MapPath("../news.xml"));
}
protected void deleteEntry(int selectIndex)
{
XmlDocument news = new XmlDocument();
news.Load(Server.MapPath("../news.xml"));
XmlNode xmlnode = news.DocumentElement.ChildNodes.Item(selectIndex);
xmlnode.ParentNode.RemoveChild(xmlnode);
news.Save(Server.MapPath("../news.xml"));
}
I haven't updated deleteEntry() and you can see, I was using the array index but need to delete the article element based on the article id being passed. And when adding an entry, I need to set the id to the last elements id + 1. Yes, I know SQL would be 100 times easier, but I don't have access so... help?
Linq to XML should make this a lot simpler. Here would be the equivalent of what you are trying:
public void AddEntry(string title, string story)
{
var newElement = new XElement("article", new XElement("title", title), new XElement("story", story));
XDocument doc = XDocument.Parse(testXml);
var maxId = doc.Descendants("article").Attributes("id").Max(x => int.Parse(x.Value));
newElement.Add(new XAttribute("id", ++maxId));
doc.Descendants("news").First().Add(newElement);
//save the document
}
public void DeleteEntry(int selectIndex)
{
XDocument doc = XDocument.Parse(testXml);
doc.Descendants("article").Where(x => int.Parse(x.Attribute("id").Value) == selectIndex).Remove();
//save the document
}
Based on the size of your xml file and the number of requests, you may want to look into other approaches than loading the document, and saving it for each call to add and delete.
EDIT: Note that you would need to add null checks to the above code...
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace LinqToXML
{
class Program
{
static void Main(string[] args)
{
int ch;
do
{
Console.WriteLine("Enter the operation you want to execute");
Console.WriteLine("Press 1 to show previous record");
Console.WriteLine("Press 2 to add new record");
Console.WriteLine("Press 3 to delete record");
Console.WriteLine("Press 4 to update record");
Record RecordObject = new Record();
int UserChoice = Convert.ToInt32(Console.ReadLine());
switch (UserChoice)
{
case 1:
RecordObject.ShowRecord();
break;
case 2:
RecordObject.AddRecord();
break;
case 3:
RecordObject.DeleteRecord();
break;
case 4:
RecordObject.UpdateRecord();
break;
default:
Console.WriteLine("Invalid Option");
break;
}
Console.WriteLine("\tDo you Want to CONTINUE?\n\t1.YES\n\t2.NO");
ch = Convert.ToInt32(Console.ReadLine());
} while (ch == 1);
}
}
class Info
{
public string StudentName { get; set; }
public int StudentId { get; set; }
public int StudentAge { get; set; }
public string StudentCity { get; set; }
}
class Record
{
string fileAddress = #"C:\XML.xml";
XmlDocument doc = new XmlDocument();
public void ShowRecord()
{
if (File.Exists(fileAddress))
{
string line;
using (StreamReader sr = new StreamReader(fileAddress))
{
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
Console.ReadLine();
}
}
else
{
Console.WriteLine("No record exist");
}
}
public void AddRecord()
{
Console.WriteLine("Enter Student Name :");
string StuName = Console.ReadLine();
Console.WriteLine("Enter Student Age :");
int StuAge = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter Student City :");
string StuCity = Console.ReadLine();
Info InfoObj = new Info();
InfoObj.StudentName = StuName;
InfoObj.StudentAge = StuAge;
InfoObj.StudentCity = StuCity;
FileStream FileStreamObj = null;
if (File.Exists(fileAddress))
{
FileStreamObj = new FileStream(fileAddress, FileMode.Open, FileAccess.ReadWrite);
FileStreamObj.Close();
XmlDocument doc = new XmlDocument();
doc.Load(fileAddress);
XmlNodeList nodes = doc.SelectNodes("//students/student");
int nodeCount = nodes.Count;
nodeCount++;
XmlNodeList students = doc.SelectNodes("//students");
foreach (XmlNode student in students)
{
XmlNode parentNode = doc.CreateElement("student");
XmlAttribute attribute = doc.CreateAttribute("id");
attribute.Value = nodeCount.ToString();
parentNode.Attributes.Append(attribute);
student.AppendChild(parentNode);
XmlNode studentName = doc.CreateElement("studentName");
studentName.InnerText = StuName;
parentNode.AppendChild(studentName);
XmlNode studentAge = doc.CreateElement("studentAge");
studentAge.InnerText = StuAge.ToString();
parentNode.AppendChild(studentAge);
XmlNode studentCity = doc.CreateElement("studentCity");
studentCity.InnerText = StuCity;
parentNode.AppendChild(studentCity);
doc.Save(fileAddress);
}
}
else
{
FileStreamObj = new FileStream(fileAddress, FileMode.Create, FileAccess.ReadWrite);
FileStreamObj.Close();
int StudentId = 1;
XmlDocument doc = new XmlDocument();
XmlNode rootNode = doc.CreateElement("students");
doc.AppendChild(rootNode);
XmlNode parentNode = doc.CreateElement("student");
XmlAttribute attribute = doc.CreateAttribute("id");
attribute.Value = StudentId.ToString();
parentNode.Attributes.Append(attribute);
rootNode.AppendChild(parentNode);
XmlNode studentName = doc.CreateElement("studentName");
studentName.InnerText = StuName;
parentNode.AppendChild(studentName);
XmlNode studentAge = doc.CreateElement("studentAge");
studentAge.InnerText = StuAge.ToString();
parentNode.AppendChild(studentAge);
XmlNode studentCity = doc.CreateElement("studentCity");
studentCity.InnerText = StuCity;
parentNode.AppendChild(studentCity);
doc.Save(fileAddress);
}
}
public void UpdateRecord()
{
doc.Load(fileAddress);
Console.WriteLine("Enter ID of the record you want to update");
int InputChoice = Convert.ToInt32(Console.ReadLine());
Info infoObj = new Info();
XmlElement element = doc.DocumentElement;
XmlNode nodeElement = element.SelectSingleNode("student[#id='" + InputChoice + "']");
if (nodeElement == null)
{
Console.WriteLine("Record doesn't exist");
}
else
{
string oldName = nodeElement.ChildNodes[0].InnerText;
string oldAge = nodeElement.ChildNodes[1].InnerText;
string oldCity = nodeElement.ChildNodes[2].InnerText;
infoObj.StudentName = oldName;
infoObj.StudentAge = Convert.ToInt32(oldAge);
infoObj.StudentCity = oldCity;
Console.WriteLine("Old Values are:\n\tName: " + infoObj.StudentName + "\n\tAge" + infoObj.StudentAge + " \n\tCity" + infoObj.StudentCity + "");
Console.WriteLine("Enter new name");
string newName = Console.ReadLine();
Console.WriteLine("Enter new Age");
int newAge = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter new city");
string newCity = Console.ReadLine();
infoObj.StudentName = newName;
infoObj.StudentAge = newAge;
infoObj.StudentCity = newCity;
nodeElement.ChildNodes[0].InnerText = infoObj.StudentName;
nodeElement.ChildNodes[1].InnerText = infoObj.StudentAge.ToString();
nodeElement.ChildNodes[2].InnerText = infoObj.StudentCity;
doc.Save(fileAddress);
}
}
public void DeleteRecord()
{
doc.Load(fileAddress);
Console.WriteLine("Enter the Id you want to delete");
string inputValue = Console.ReadLine();
XmlElement element = doc.DocumentElement;
XmlNode nodeElement = element.SelectSingleNode("student[#id='" + inputValue + "']");
if (nodeElement == null)
{
Console.WriteLine("Record doesn't exist");
}
else
{
element.RemoveChild(nodeElement);
doc.Save(fileAddress);
Console.WriteLine("Sucessfully deleted");
}
}
}
}

Categories

Resources