I have a xml file as:-
<Data>
<Caption>
</Caption>
</Data>
I added a new child CData in the the following code
foreach (XmlNode item in childNode.ChildNodes)
{
if (item.Name == "Data")
{
XmlCDataSection CData;
CData = xml2.CreateCDataSection("All Jane Austen novels 25% off starting 3/23!");
item.InsertBefore(CData, item.FirstChild);
foreach (XmlNode itemC in item.ChildNodes)
{
if (itemC.Name == "Caption")
{
XmlElement getTemplateID = xml2.CreateElement("TempalteID");
getTemplateID.InnerText = "10010";
itemC.AppendChild(getTemplateID);
//if (OptionsData[0].Key == "NoChilds")
//{
// XmlElement Getnochild = itemDoc.CreateElement("CaptionOptions");
// Getnochild.InnerText = "";
// itemC.AppendChild(Getnochild);
//}
//else
//{
XmlNode elemCap = xml2.CreateNode(XmlNodeType.Element, "CaptionOptions", null);
itemC.AppendChild(elemCap);
XmlElement Getelem1 = xml2.CreateElement("CaptionField");
elemCap.AppendChild(Getelem1);
XmlElement elem2 = xml2.CreateElement("FieldID");
XmlElement elem3 = xml2.CreateElement("FieldID");
elem2.InnerText = "#FieldId1";
elem3.InnerText = "#FieldId2";
XmlElement elem4 = xml2.CreateElement("TextString");
XmlElement elem5 = xml2.CreateElement("TextString");
elem4.InnerText = "#TextString1";
elem5.InnerText = "#TextString2";
Getelem1.AppendChild(elem2);
Getelem1.AppendChild(elem4);
Getelem1.AppendChild(elem3);
Getelem1.AppendChild(elem5);
//}
}
}
}
}
Now my final xml is coming as
<Data>
<![CDATA[All Jane Austen novels 25% off starting 3/23!]]>
<Caption>
<TempalteID>10010</TempalteID>
<CaptionOptions><CaptionField>
<FieldID>#FieldId1</FieldID>
<TextString>#TextString1</TextString>
<FieldID>#FieldId2</FieldID>
<TextString>#TextString2</TextString>
</CaptionField></CaptionOptions>
</Caption>
</Data>
But I want to make it as the following way....
<Data><![CDATA[<Caption xmlns="http://www.iin.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.happy.xsd">
<TemplateID>T000114-NOW</TemplateID>
<CaptionOptions>
<CaptionField>
<FieldID>NOW1</FieldID>
<TextString>"Ep 01"</TextString>
</CaptionField>
<CaptionField>
<FieldID>NOW2</FieldID>
<TextString>""</TextString>
</CaptionField>
</CaptionOptions>
</Caption>]]>
</Data>
So as you can see I basically wanted my newly added child CData to make <Caption> as it's child. So basically I want to create a child and make an existing child as it's child.(But I don't think I would still get the same format?")
How to do it?
Using xml Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Runtime.InteropServices;
namespace ConsoleApplication23
{
class Program
{
static void Main(string[] args)
{
string xml = "<Data><Caption xmlns=\"http://www.iin.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.happy.xsd\"/></Data>";
XDocument doc = XDocument.Parse(xml);
XElement caption = doc.Descendants("Data").FirstOrDefault();
caption.Add(new XElement("TemplateID","T000114-NOW"));
XElement options = new XElement("CaptionOptions");
caption.Add(options);
foreach (Field field in Field.fields)
{
XElement newField = new XElement("CaptionField", new object[] { new XElement("FieldID", field.ID), new XElement("TextString", field.text)});
options.Add(newField);
}
}
}
public class Field
{
public static List<Field> fields = new List<Field>() {
new Field() { ID = "NOW1", text = "Ep 01"},
new Field() { ID = "Ep 01", text = ""}
};
public string ID { get; set; }
public string text { get; set; }
}
}
If I understand right, what you want to do is storing XML data in CDATA element. I want to remind you, that this is not what CDATA was intended to be used for, but here is example how to do that:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'>" +
"<title>Pride And Prejudice</title>" +
"</book>");
//Add the new node to the document.
XmlElement root = doc.DocumentElement;
XmlCDataSection CData;
CData = doc.CreateCDataSection(root.InnerXml);
root.RemoveAll();
root.AppendChild(CData);
doc.Save(Console.Out);
Related
I need to create an XML document like this:
<Root>
<Data>
<Name>Name1</Name>
<Surname>Surname1</Surname>
<Gender>M</Gender>
</Data>
<Data>
<Name>Name2</Name>
<Surname>Surname2</Surname>
<Gender>F</Gender>
</Data>
</Root>
I've got the Xpath of the XML Elements, so I've create the following class
class XpathFieldValue
{
public string Xpath { get; set; }
public string Value { get; set; }
}
and then the following method
public static void CreateXml()
{
List<XpathFieldValue> fieldValues = new List<XpathFieldValue> {
new XpathFieldValue{ Xpath="/Root/Data/Name", Value="Name1" },
new XpathFieldValue{ Xpath="/Root/Data/Surname", Value="Surname1" },
new XpathFieldValue{ Xpath="/Root/Data/Gender", Value="M"},
new XpathFieldValue{ Xpath="/Root/Data/Name", Value="Name2" },
new XpathFieldValue{ Xpath="/Root/Data/Surname", Value="Surname2" },
new XpathFieldValue{ Xpath="/Root/Data/Gender", Value="F"}
};
XmlDocument document = new XmlDocument();
document.LoadXml("<Root/>");
foreach (XpathFieldValue fieldValue in fieldValues)
{
Set(document, fieldValue.Xpath, fieldValue.Value);
}
document.Save(#"C:\Temp\xmlDocOut.xml");
}
I've copyed the Set method from here: link
But when I run it it creates only the last parth of XML
<Root>
<Data>
<Name>Name2</Name>
<Surname>Surname2</Surname>
<Gender>F</Gender>
</Data>
</Root>
Can anyone help me?
XPath isn't really intended to generate documents but to access em.
Another (probably better) approach would be to serialize it.
But, since the question requires the fields of xml to be variable, serialization isn't a viable way. i STRONGLY advise you to change this requirement and you'll see why in the following example:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
using (var writer = new System.IO.StreamWriter(#"C:\Users\luigi.trabacchin\Desktop\asd.xml"))
{
var doc = new System.Xml.XmlDocument();
var root = doc.CreateElement("Root");
doc.AppendChild(root);
for (var i = 0; i <= 1; i++)
{
var dataNode = doc.CreateElement("Data");
root.AppendChild(dataNode);
{
var node = doc.CreateElement("Name");
dataNode.AppendChild(node);
var text = doc.CreateTextNode($"Name {i}");
node.AppendChild(text);
}
{
var node = doc.CreateElement("Surname");
dataNode.AppendChild(node);
var text = doc.CreateTextNode($"Surname {i}");
node.AppendChild(text);
}
{
var node = doc.CreateElement("Gender");
dataNode.AppendChild(node);
var text = doc.CreateTextNode(i %2 == 0 ? "M" : "F");
node.AppendChild(text);
}
}
doc.Save(writer);
}
Console.WriteLine("Hello World!");
}
}
}
It quickly becomes very tedious and hard to work with.
Still i hope this answer your question.
Next time, maybe, state all the requirements directly in the question!
<?xml version="1.0" encoding="UTF-8"?>
<message xmlns="jabber:client" to="dev_345#localhost/unityXMPP" type="chat" xml:lang="en" from="dev_272#localhost/unityXMPP">
<archived xmlns="urn:xmpp:mam:tmp" id="1503375414608430" by="dev_345#localhost" />
<stanza-id xmlns="urn:xmpp:sid:0" id="1503375414608430" by="dev_345#localhost" />
<body>hi</body>
</message>
I wanted to parse the inner XML to fetch the id attribute.
I have created namespace whatsoever I have found. I am able to get to, from attributes. Below is the code in c#.
string value = "<message xmlns=\"jabber:client\" to=\"dev_345#localhost/unityXMPP\" type=\"chat\" xml:lang=\"en\" from=\"dev_272#localhost/unityXMPP\"><archived xmlns=\"urn:xmpp:mam:tmp\" id=\"1503375414608430\" by=\"dev_345#localhost\" /><stanza-id xmlns=\"urn:xmpp:sid:0\" id=\"1503375414608430\" by=\"dev_345#localhost\" /><body>hi</body></message>";
XmlDocument xmlDoc = new XmlDocument ();
XmlNamespaceManager namespaces = new XmlNamespaceManager (xmlDoc.NameTable);
namespaces.AddNamespace ("ns", "jabber:client");
namespaces.AddNamespace ("ns1", "urn:xmpp:mam:tmp");
xmlDoc.LoadXml (value);
XmlNode messageNode = xmlDoc.SelectSingleNode ("/ns:message", namespaces);
string sender = messageNode.Attributes ["from"].Value;
string receiver = messageNode.Attributes ["to"].Value;
string message = messageNode.InnerText;
XmlNode timeStampNode = xmlDoc.SelectSingleNode ("/ns:message/ns1:archived");
string timestamp = timeStampNode.Attributes ["id"].Value;
Does this help? I used LINQ To Xml
string xmltext = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><message xmlns=\"jabber:client\" to=\"dev_345#localhost/unityXMPP\" type=\"chat\" xml:lang=\"en\" from=\"dev_272#localhost/unityXMPP\"> <archived xmlns=\"urn:xmpp:mam:tmp\" id=\"1503375414608430\" by=\"dev_345#localhost\" /> <stanza-id xmlns=\"urn:xmpp:sid:0\" id=\"1503375414608430\" by=\"dev_345#localhost\" /> <body>hi</body></message>";
var xdoc = XDocument.Parse(xmltext);
foreach (var item in xdoc.Root.Descendants())
{
if (item.Name.LocalName == "archived")
Console.WriteLine(item.Attribute("id").Value);
}
It's better to use the XPath, if you dont want to de-/serialize the xml into an object (Link).
Or you can use the serialization, it's a very easy way to use json or xml inside your solution (Link 1, Link 2).
Try following xml linq to get all the data
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var message = doc.Descendants().Where(x => x.Name.LocalName == "message").Select(x => new {
to = (string)x.Attribute("to"),
type = (string)x.Attribute("type"),
lang = (string)x.Attributes().Where(y => y.Name.LocalName == "lang").FirstOrDefault(),
from = (string)x.Attribute("from"),
messages = x.Elements().Select(y => new {
name = y.Name.LocalName,
id = (string)y.Attribute("id"),
by = (string)y.Attribute("by"),
value = (string)y
}).ToList()
}).FirstOrDefault();
}
}
}
Here is the XML
<?xml version="1.0" encoding="UTF-8"?>
<Data_Speed>
<Tech ID = "UMTS">
<Coverage ID="Dense_Urban">
<DownLoad_Speed>10</DownLoad_Speed>
<Upload_Speed>20</Upload_Speed>
</Coverage>
<Coverage ID="Urban">
<DownLoad_Speed>30</DownLoad_Speed>
<Upload_Speed>40</Upload_Speed>
</Coverage>
<Coverage ID="SubUrban">
<DownLoad_Speed>50</DownLoad_Speed>
<Upload_Speed>60</Upload_Speed>
</Coverage>
</Tech>
<Tech ID = "UMTS900">
<Coverage ID="Dense_Urban">
<DownLoad_Speed>11</DownLoad_Speed>
<Upload_Speed>12</Upload_Speed>
</Coverage>
<Coverage ID="Urban">
<DownLoad_Speed>13</DownLoad_Speed>
<Upload_Speed>14</Upload_Speed>
</Coverage>
<Coverage ID="SubUrban">
<DownLoad_Speed>15</DownLoad_Speed>
<Upload_Speed>16</Upload_Speed>
</Coverage>
</Tech>
<Tech ID = "4G800">
<Coverage ID="Dense_Urban">
<DownLoad_Speed>30</DownLoad_Speed>
<Upload_Speed>42</Upload_Speed>
</Coverage>
<Coverage ID="Urban">
<DownLoad_Speed>50</DownLoad_Speed>
<Upload_Speed>34</Upload_Speed>
</Coverage>
<Coverage ID="SubUrban">
<DownLoad_Speed>45</DownLoad_Speed>
<Upload_Speed>46</Upload_Speed>
</Coverage>
<Coverage ID="Rural">
<DownLoad_Speed>47</DownLoad_Speed>
<Upload_Speed>48</Upload_Speed>
</Coverage>
<Coverage ID="Variable">
<DownLoad_Speed>15</DownLoad_Speed>
<Upload_Speed>52</Upload_Speed>
</Coverage>
<Coverage ID="Outdoor">
<DownLoad_Speed>25</DownLoad_Speed>
<Upload_Speed>22</Upload_Speed>
</Coverage>
</Tech>
</Data_Speed>
So how could I get value of DownLoad_Speed> & UpLoad_Speed> element by given Coverage ID Urban> and Tech ID UMTS900>? Say, if I give tech id value = "UMTS900" and coverage id value "Urban", I'd like to have string value dwnload_speed = 13 and Upload_Speed = 14 as result.
Using Linq to Xml
XDocument doc = XDocument.Load(filepath);
//ex...
string technology = "UMTS900";
string coverage = "Dense_Urban";
var result = doc.Descendants("Tech")
.Where(x=> (string)x.Attribute("ID") == technology)
.Elements("Coverage")
.Where(x=>(string)x.Attribute("ID")== coverage)
.Select(x=> new
{
Dowload_Speed = (string)x.Element("DownLoad_Speed"),
Upload_Speed = (string)x.Element("Upload_Speed")
});
Check this Demo
You need to open XML document
XmlDocument _document = new XmlDocument();
byte[] bytes = File.ReadAllBytes(filePath);
string xml = Encoding.UTF8.GetString(bytes);
try
{
_document.LoadXml(xml);
}
catch (XmlException e)
{
//exception handling
}
var doc = (XmlDocument)_document.CloneNode(true);
XmlNode node = doc.GetElementsByTagName("your child node name");
Once you get your node then you can do necessary thing with it
string techId = "UMTS900";
string coverageId = "SUBURBAN";
int downloadSpeed = 0;
int uploadSpeed = 0;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"C:\....\DataSpeed.xml");
XmlNodeList techTags = xmlDoc.GetElementsByTagName("Tech");
foreach (XmlNode techTag in techTags)
{
if (techTag.Attributes["ID"].Value.Equals(techId,StringComparison.OrdinalIgnoreCase))
{
XmlNodeList coverageTags = techTag.ChildNodes;
foreach (XmlNode coverageTag in coverageTags)
{
if (coverageTag.Attributes["ID"].Value.Equals(coverageId, StringComparison.OrdinalIgnoreCase))
{
downloadSpeed =Convert.ToInt16(coverageTag.ChildNodes[0].InnerText);
uploadSpeed = Convert.ToInt16(coverageTag.ChildNodes[1].InnerText);
break;
}
}
break;
}
}
if (downloadSpeed == 0 && uploadSpeed == 0)
{
Console.WriteLine("Specified Tech Id and Coverage Id not found");
}
else
{
Console.WriteLine("Download Speed is {0}. Upload Speed is {1}.",downloadSpeed,uploadSpeed);
}
Here is solution using XmlReader with xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication4
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
string id = "UMTS900";
object coverages = null;
while (!reader.EOF)
{
if (reader.Name != "Tech")
{
reader.ReadToFollowing("Tech");
}
if (!reader.EOF)
{
XElement tech = (XElement)XElement.ReadFrom(reader);
if((string)tech.Attribute("ID") == id)
{
coverages = tech.Descendants("Coverage").Select(x => new
{
id = (string)x.Attribute("ID"),
downLoad_Speed = (int)x.Element("DownLoad_Speed"),
upLoad_Speed = (int)x.Element("Upload_Speed"),
}).ToList();
break;
}
}
}
}
}
}
i'm trying to read xml file and update all it's value my xml was
<adf>
<prospect>
<requestdate>2015-10-29 07-38-22</requestdate>
<id sequence="1" source="admin.ss.com">admin.ss.com</id>
<vehicle interest="buy" status="">
<id sequence="1" source=""></id>
<year></year>
<make></make>
<model>camry</model>
<vin></vin>
<stock></stock>
<trim></trim>
</vehicle>
<customer>
<contact primarycontact="1">
<name part="first">Jessica</name>
<name part="last">Sonntag</name>
<email>js#test.com</email>
<phone type="phone" time="day">555-585-5555</phone>
<address>
<street line="1"></street>
<city></city>
<regioncode></regioncode>
<postalcode></postalcode>
<country></country>
</address>
</contact>
<comments>Vehicle Year: 2011 Comments: </comments>
</customer>
<provider>
<name part="full">ST</name>
<service> Engine Marketing</service>
<phone>1-866-572-3952</phone>
</provider>
</prospect>
</adf>
so i select node like below
var items = (from item in xmlDoc.Descendants("requestdate")
select item).ToList();
then i can update only requestdata tag value so do i have to repeat same for all tags or is there any good way to accomplish this.
Regards
There is an easy way to do this. This one is a hidden gem. Most people may not know this. This feature came in VS2013 and it's called "Paste XML as Classes."
Save your xml (Ex: MyXml.XML)
Create a new Console project
Open the Xml in Visual studio
Copy All contents of the xml (Ctl+A, Ctl + C)
Add a new class to your project. You can give any name you like.
Go to Edit>Paste Special>Paste XML as classes.
Add another class to your project. Then add below two methods to that class.
public static string Serialise<T>(T serialisableObject)
{
var doc = new XmlDocument();
using (var stream = new StringWriter())
{
var settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
XmlWriter xmlWriter = XmlWriter.Create(stream, settings);
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
var xmlSerializer = new XmlSerializer(typeof(T));
xmlSerializer.Serialize(xmlWriter, serialisableObject, ns);
doc.LoadXml(stream.ToString());
}
return doc.InnerXml;
}
public static T Deserialise<T>(string xml)
{
T list;
using (var reader = new StringReader(xml))
{
var serialiser = new XmlSerializer(typeof(T));
list = (T)serialiser.Deserialize(reader);
}
return list;
}
Then in your console applications Main method; add this.
var myObj = new adf();
myObj.prospect = new adfProspect();
myObj.prospect.customer = new adfProspectCustomer(){comments = "dgsrtetetete"};
//populate all fields.....
var xml = MySerializer.Serialise(myObj);
File.WriteAllText(#"C:\myNewXml.xml", xml);
That's it. Same way now you can deserialise an xml object in to your class.
Try the XmlSerializer class: https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer(v=vs.110).aspx If you serialize/deserialize the xml then up dating is trivial.
If you wanted to change every phone number to "0123456789" you could do something like:
var xDoc = XDocument.Load("document.xml");
var results = from phone in xDoc.Descendants("phone") select phone;
foreach (XElement result in results)
{
element.SetValue("0123456789");
}
i have came up with solution with support two extension method i'm iterating all nodes and update.(since my xml is not too big or complicated this one would be a good solution)
with help of these two extension methods
public static void IterateThroughAllNodes(this XmlDocument doc, Action<XmlNode> elementVisitor)
{
if (doc != null && elementVisitor != null)
{
foreach (XmlNode node in doc.ChildNodes)
{
DoIterateNode(node, elementVisitor);
}
}
}
public static void IterateThrough(this XmlNodeList nodes, Action<XmlNode> elementVisitor)
{
if (nodes != null && elementVisitor != null)
{
foreach (XmlNode node in nodes)
{
DoIterateNode(node, elementVisitor);
}
}
}
private static void DoIterateNode(XmlNode node, Action<XmlNode> elementVisitor)
{
elementVisitor(node);
foreach (XmlNode childNode in node.ChildNodes)
{
DoIterateNode(childNode, elementVisitor);
}
}
then i can update my xml nodes as below
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("~/xmlmail.xml"));
var email = new XmlEmail();
doc.IterateThroughAllNodes(
delegate(XmlNode node)
{
if (node.Name.Equals("requestdate"))
node.InnerText= email.RequestDate.ToLongDateString();
if (node.Name.Equals("vehicle"))
{
XmlNodeList childs = node.ChildNodes;
childs.IterateThrough(delegate(XmlNode vnode)
{
if (vnode.Name.Equals("id"))
vnode.InnerText= email.VehicleId.ToString();
if (vnode.Name.Equals("year"))
vnode.InnerText= email.Year.ToString();
if (vnode.Name.Equals("make"))
vnode.InnerText= email.Make;
if (vnode.Name.Equals("model"))
vnode.InnerText= email.Model;
if (vnode.Name.Equals("vin"))
vnode.InnerText= email.Vin;
if (vnode.Name.Equals("trim"))
vnode.InnerText = email.Trim;
});
}
if (node.Name.Equals("customer"))
{
XmlNodeList childs = node.ChildNodes;
childs.IterateThrough(delegate(XmlNode vnode)
{
if (vnode.Attributes != null && (vnode.Name.Equals("name") && vnode.Attributes["part"].Value.Equals("first")))
vnode.InnerText= email.FirstName;
if (vnode.Attributes != null && (vnode.Name.Equals("name") && vnode.Attributes["part"].Value.Equals("last")))
vnode.InnerText= email.LastName;
if (vnode.Name.Equals("email"))
vnode.InnerText= email.Email;
if (vnode.Name.Equals("phone"))
vnode.InnerText= email.Phone;
if (vnode.Name.Equals("comments"))
vnode.InnerText= email.Comments;
if (vnode.Name.Equals("address"))
{
XmlNodeList addresschilds = vnode.ChildNodes;
addresschilds.IterateThrough(delegate(XmlNode anode)
{
if (anode.Name.Equals("street"))
anode.InnerText= email.Street;
if (anode.Name.Equals("city"))
anode.InnerText= email.City;
if (anode.Name.Equals("phone"))
anode.InnerText= email.Phone;
if (anode.Name.Equals("regioncode"))
anode.InnerText= email.RegionCode;
if (anode.Name.Equals("postalcode"))
anode.InnerText= email.Postalode;
if (anode.Name.Equals("country"))
anode.InnerText= email.Country;
});
}
});
}
});
Here is the sample XML that I am receiving from the web service.
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
xmlns:rs='urn:schemas-microsoft-com:rowset'
xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
<s:ElementType name='row' content='eltOnly'>
<s:AttributeType name='NAME' rs:number='1'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='25'
rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='DESCRIPTION' rs:number='2' rs:nullable='true'
rs:writeunknown='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='80'/>
</s:AttributeType>
<s:extends type='rs:rowbase'/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row NAME='JOE BLOW' DESCRIPTION='PROGRAMMER'/>
<z:row NAME='ANN SMITH' DESCRIPTION='FRONT DESK'/>
<z:row NAME='STEVE JOHNSON' DESCRIPTION='TESTER'/>
</rs:data>
</xml>
I'm not sure how to go about getting to the <rs:data> node. I eventually want to enumerate through each <z:row> and get the attributes NAME and DESCRPTION. The webservice returns this to me as a string so I load the string into an XMLDocument like this:
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(xmlString);
Now, I'm not sure if I need to use a XmlNamespaceManager in order to tel my xDoc to import the <s:Schema>
I've tried to select a single node with an XPath with no luck because of the prefix rs.
XmlNode xNode = xDoc.SelectSingleNode("/rs:data");
If there is any further information needed, please ask.
If you are taking the xml as a string try parsing it like instead of using Load()
var xml = XDocument.Parse(xmlstring);
You have to use the namespace to get hold of the data properly.
XNamespace ns = "#RowsetSchema";
foreach (var element in xml.Descendants().Elements(ns + "row"))
{
Console.WriteLine ("Name = " + element.Attribute("NAME").Value + ", " + "Description = " + element.Attribute("DESCRIPTION").Value);
}
Using xml with linq it can be done like this:
XDocument xmlDoc = new XDocument();
xmlDoc = XDocument.Parse(xml);
XNamespace ns = "#RowsetSchema";
var namesDescs = from namesDesc in xmlDoc.Descendants().Elements(ns + "row")
select new
{
name = namesDesc.Attribute("NAME").Value,
description = namesDesc.Attribute("DESCRIPTION").Value,
};
Here's some classes for handling your xml, using these extensions: http://searisen.com/xmllib/extensions.wiki
public class Test
{
XElement self;
public Test(XElement self)
{
this.self = self;
}
public RSDataRow[] DataRows
{
get
{
if (null == _DataRows)
{
_DataRows = self.GetEnumerable("rs:data/z:row", xrow => new RSDataRow(xrow)).ToArray();
}
return _DataRows;
}
}
RSDataRow[] _DataRows;
}
[DebuggerDisplay("{Name}")]
public class RSDataRow
{
XElement self;
public RSDataRow(XElement self)
{
this.self = self;
}
public string Name
{
get { return self.Get("NAME", string.Empty); }
}
public string Description
{
get { return self.Get("DESCRIPTION", string.Empty); }
}
}
You use it like:
Test test = new Test(XElement.Parse(xmlstring));
foreach (RSDataRow row in test.DataRows)
{
string name = row.Name;
string desc = row.Description;
}