XML Root Element Parsing - c#

I am parsing an xml file using the following which works well but my question is how do I get the value from the tag <themename> because I am using oXmlNodeList for my loop. Just don't want to be writing a separate routine for one tag.
XmlDocument xDoc = new XmlDocument();
List<active_theme> listActiveTheme = new List<active_theme>();
string path = AppDomain.CurrentDomain.BaseDirectory + #"themes\test\configuration.xml";
xDoc.Load(AppDomain.CurrentDomain.BaseDirectory + #"themes\test\configuration.xml");
//select a list of Nodes matching xpath expression
XmlNodeList oXmlNodeList = xDoc.SelectNodes("configuration/masterpages/masterpage");
Guid newGuid = Guid.NewGuid();
foreach (XmlNode x in oXmlNodeList)
{
active_theme activetheme = new active_theme();
string themepage = x.Attributes["page"].Value;
string masterpage = x.Attributes["name"].Value;
activetheme.active_theme_id = newGuid;
activetheme.theme = "Dark";
activetheme.page = themepage;
portalContext.AddToActiveTheme(activetheme);
}
portalContext.SaveChanges();
XML File for theme configuration
<configuration>
<themename>Dark Theme</themename>
<masterpages>
<masterpage page="Contact" name="default.master"></masterpage>
<masterpage page="Default" name="default.master"></masterpage>
<masterpage page="Blue" name="blue.master"></masterpage>
<masterpage page="red" name="red.master"></masterpage>
</masterpages>
</configuration>

I'd use LINQ to XML to start with. Something like this:
var doc = XDocument.Load(...);
var themeName = doc.Root.Element("themename").Value;
Guid themeGuid = Guid.NewGuid();
foreach (var element in doc.Root.Element("masterpages").Elements("masterpage"))
{
ActiveTheme theme = new ActiveTheme
{
ThemeName = themeName,
ActiveThemeId = themeGuid,
Page = element.Attribute("page").Value,
MasterPage = element.Attribute("name").Value
};
portalContent.AddToActiveTheme(theme);
}
portalContext.SaveChanges();

Related

C# (Xamarin): looping through XML

I have a Xamarin (C#) project, where I am trying to loop through some XML, but for some reason my code is not working.
This is what I have now:
DeviceList = new List<DeviceInfo>();
string ResultStatus = "";
string ResultDevice = "";
var result = Encoding.Default.GetString(e.Result);
result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + result;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(result);
string xPathStatus = "ed_listdevices";
var nodes = xmlDoc.SelectNodes(xPathStatus);
foreach (XmlNode xNode in nodes) {
ResultStatus = xNode.SelectSingleNode("//status").InnerText;
ResultDevice = xNode.SelectSingleNode("//device").InnerText;
}
if (ResultStatus.ToLower() == "ok") {
XmlDocument deviceDoc = new XmlDocument();
deviceDoc.LoadXml(result);
var deviceNodes = deviceDoc.SelectNodes(xPathStatus + "/device");
//foreach(XmlNode dNode in deviceNodes) {
for (int i = 0; i < deviceNodes.Count; i++) {
DeviceList.Add(new DeviceInfo() {
DeviceID = deviceNodes[i].SelectSingleNode("//id").InnerXml,
DeviceName = deviceNodes[i].SelectSingleNode("//name").InnerXml,
DeviceExtraName = "",
DeviceOnlineStatus = deviceNodes[i].SelectSingleNode("//status").InnerXml,
Location = deviceNodes[i].SelectSingleNode("//address").InnerXml,
Time = deviceNodes[i].SelectSingleNode("//time").InnerXml
});
}
}
When I step though the code I get the "ResultStatus" and "ResultDevice" correctly, and when I get to the
for (int i = 0; i < deviceNodes.Count; i++)
the "deviceNodes" variable have a count of 91, and I can see all the individual xml elements that I am suppose to get from the webservice I am calling.
However, when I loop through deviceNodes[i] I only get values from the very first XML element (yes, the value of "i" does change). In other words, my DeviceList is filled with 91 entries with the same values.
Am I missing something obvious?? What am I doing wrong since this isn't working??
PS: I have also tried using a foreach (XmlNode node in deviceNodes) but the result was the same.
"//" in the selector tells it to search from the root node of the document. If you want to search locally under the "current" node, remove the "//"

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
}

How to get xml element values using XmlNodeList in c#

I need to store the element values which are inside the nodes "member" . I have tried the following code but I can't achieve it. How to get the values. Any help would be appreciated
XML:
<ListInventorySupplyResponse xmlns="http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/">
<ListInventorySupplyResult>
<InventorySupplyList>
<member>
<SellerSKU>043859634910</SellerSKU>
<FNSKU>X000IA4045</FNSKU>
<ASIN>B005YV4DJO</ASIN>
<Condition>NewItem</Condition>
<TotalSupplyQuantity>7</TotalSupplyQuantity>
<InStockSupplyQuantity>7</InStockSupplyQuantity>
<EarliestAvailability>
<TimepointType>Immediately</TimepointType>
</EarliestAvailability>
<SupplyDetail>
</SupplyDetail>
</member>
</InventorySupplyList>
</ListInventorySupplyResult>
<ResponseMetadata>
<RequestId>58c9f4f4-6f60-496a-8d71-8fe99ce301c9</RequestId>
</ResponseMetadata>
</ListInventorySupplyResponse>
C# Code:
string a = Convert.ToString(oInventorySupplyRes.ToXML());
XmlDocument oXdoc = new XmlDocument();
oXdoc.LoadXml(a);
XmlNodeList oInventorySupplyListxml = oXdoc.SelectNodes("//member");
foreach (XmlNode itmXml in oInventorySupplyListxml)
{
// var cond = itmXml.InnerXml.ToString();
var asinVal = itmXml.SelectSingleNode("ASIN").Value;
var TotalSupplyQuantityVal = itmXml.SelectSingleNode("TotalSupplyQuantity").Value;
}
ResultView : "Enumeration yielded no results" and count = 0;
Edit 1:
string a = Convert.ToString(oInventorySupplyRes.ToXML());
var status = oInventorySupplyResult.InventorySupplyList;
XmlDocument oXdoc = new XmlDocument();
var doc = XDocument.Parse(a);
var r = doc.Descendants("member")
.Select(member => new
{
ASIN = member.Element("ASIN").Value,
TotalSupplyQuantity = member.Element("TotalSupplyQuantity").Value
});
private string mStrXMLStk = Application.StartupPath + "\\Path.xml";
private System.Xml.XmlDocument mXDoc = new XmlDocument();
mXDoc.Load(mStrXMLStk);
XmlNode XNode = mXDoc.SelectSingleNode("/ListInventorySupplyResult/InventorySupplyList/member");
if (XNode != null)
{
int IntChildCount = XNode.ChildNodes.Count;
for (int IntI = 1; IntI <= IntChildCount ; IntI++)
{
string LocalName = XNode.ChildNodes[IntI].LocalName;
XmlNode Node = mXDoc.SelectSingleNode("/Response/" + LocalName);
// Store Value in Array assign value by "Node.InnerText"
}
}
Try This Code. Its Worked
try using this xpath
string xPath ="ListInventorySupplyResponse/ListInventorySupplyResult
/InventorySupplyList/member"
XmlNodeList oInventorySupplyListxml = oXdoc.SelectNodes(xpath);
when you do "//member", then, the code is trying to look for element named member from the root level, which is not present at the root level, rather it is nested beneath few layers.
I think this will help you..
string a = Convert.ToString(oInventorySupplyRes.ToXML());
XmlDocument oXdoc = new XmlDocument();
oXdoc.LoadXml(a);
XmlNodeList fromselectors;
XmlNodeList toselectors;
XmlElement root = oXdoc.DocumentElement;
fromselectors = root.SelectNodes("ListInventorySupplyResult/InventorySupplyList/member/ASIN");
toselectors = root.SelectNodes("ListInventorySupplyResult/InventorySupplyList/member/TotalSupplyQuantity");
foreach (XmlNode m in fromselectors)
{
you will have value in `m.InnerXml` use it whereever you want..
}
foreach (XmlNode n in toselectors)
{
you will have value in `n.InnerXml` use it whereever you want..
}

Obtain XML child nodes using C#

This is my first time attempting to parse XML using C# and feel like I'm running in circles right now. I am calling a WCF web service which, based upon user input, conducts a search through a database against company names. It returns the results in an XML document with each entry formatted as it is below.
Given this XML structure, how would I go about obtaining the values for the d:AccountId and d:Name nodes using C#?
<entry>
<id></id>
<title type=\"text\"></title>
<updated></updated>
<author><name /></author>
<link rel=\"edit\" title=\"Account\" href=\"AccountSet\" />
<category term=\"Microsoft.Crm.Sdk.Data.Services.Account\" scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" />
<content type=\"application/xml\">
<m:properties>
<d:neu_UniqueId></d:neu_UniqueId>
<d:AccountId m:type=\"Edm.Guid\"></d:AccountId>
<d:Name></d:Name>
</m:properties></content>
</entry>
Here is my first attempt. The program threw an exception at the node3 variable.
try
{
WebRequest myWebRequest = WebRequest.Create(URL);
myWebRequest.PreAuthenticate = true;
myWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
//myWebRequest.Headers.Add("Access-Control-Allow-Origin", url);
WebResponse myWebResponse = myWebRequest.GetResponse();
Stream myFileStreamResult = myWebResponse.GetResponseStream();
Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(myFileStreamResult, encoder);
results = readStream.ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(results);
XmlNodeList parentNode = xmlDoc.GetElementsByTagName("entry");
foreach (XmlNode childNode in parentNode)
{
string node = childNode.ToString();
string node2 = childNode.Value;
string node3 = childNode.Attributes["title"].Value;
string node7 = childNode.Attributes["m:properties"].Value;
string node8 = childNode.Attributes["m:properties\\d:AccountId"].Value;
string node9 = childNode.Attributes["m:properties\\d:Name"].Value;
string node10 = childNode.Attributes["m:properties\\d:AccountId"].Value;
}
}
Assuming the API reliably returns that XML structure you can simply specify the path to the node as "/entry/m:properties" then call get children. After that you'll want to loop over those nodes, checking for the nodes you want.
Currently your foreach loop is attempting all of those operations on the <id></id> node which causes an Exception because there is no "title" attribute.
So to give some sample code, you're looking for something like this;
XmlNode props = root.SelectSingleNode("/entry/m:properties");
for (int i = 0; i < props.ChildNodes.Count; i++)
{
if (propes.ChildNodes[i].Name = "node I want")
{
//do something
}
}
Or if you specifically only want those two values, then just use SelectSingleNode with the full path to that node. From your question it sounds like there is no reason to use iteration. So you could simply do;
string accountName = root.SelectSingleNode("/entry/m:properties/d:Name").InnerXml;
to get the account name.
using Linq2Xml will probably be a little easier.
var xml = "<entry xmlns:m=\"ns1\" xmlns:n=\"ns2\" xmlns:d=\"ns3\">" +
"<id></id>" +
"<title type=\"text\"></title>" +
"<updated></updated>" +
"<author><name /></author>" +
"<link rel=\"edit\" title=\"Account\" href=\"AccountSet\" />" +
"<category term=\"Microsoft.Crm.Sdk.Data.Services.Account\" scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" />" +
"<content type=\"application/xml\">" +
"<m:properties>" +
"<d:neu_UniqueId></d:neu_UniqueId>" +
"<d:AccountId m:type=\"Edm.Guid\">Account ID</d:AccountId>" +
"<d:Name>Account Name</d:Name>" +
"</m:properties></content>" +
"</entry>";
const string namespaceM = "ns1";
const string namespaceD = "ns3";
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
using (var reader = XmlReader.Create(stream))
{
var document = XDocument.Load(reader, LoadOptions.None);
var contentNode = document.Elements().First().Elements().First(e => e.Name.LocalName == "content");
var propertiesNode = contentNode.Elements().First(d => d.Name.LocalName == "properties" && d.Name.Namespace == namespaceM);
var accountIdNode = propertiesNode.Elements().First(d => d.Name.LocalName == "AccountId" && d.Name.Namespace == namespaceD);
var nameNode = propertiesNode.Elements().First(d => d.Name.LocalName == "Name" && d.Name.Namespace == namespaceD);
var accountIdText = accountIdNode.Value;
var nameText = nameNode.Value;
}
}

How to Search and Navigate XML Nodes

I have the following XML :
<LOCALCELL_V18 ID = "0x2d100000">
<MXPWR ID = "0x3d1003a0">100</MXPWR>
</LOCALCELL_V18>
<LOCALCELL_V18 ID = "0x2d140000">
<MXPWR ID = "0x3d1403a0">200</MXPWR>
</LOCALCELL_V18>
<LOCALCELL_V18 ID = "0x2d180000">
<MXPWR ID = "0x3d1803a0">300</MXPWR>
</LOCALCELL_V18>
I want to get the inner text of each <MXPWR>. however, it is not allowed to use ID# to locate the inner text since it is not always the same. here is my code:
XmlNodeList LocalCell = xmlDocument.GetElementsByTagName("LOCALCELL_V18");
foreach (XmlNode LocalCell_Children in LocalCell)
{
XmlElement MXPWR = (XmlElement)LocalCell_Children;
XmlNodeList MXPWR_List = MXPWR.GetElementsByTagName("MXPWR");
for (int i = 0; i < MXPWR_List.Count; i++)
{
MaxPwr_form_str = MXPWR_List[i].InnerText;
}
}
Any opinion will be appreciated.
I would use xpath. It was designed for just this sort of problem. Something like:
using System.Xml;
using System.Xml.XPath;
....
string fileName = "data.xml"; // your file here
XPathDocument doc = new XPathDocument(fileName);
XPathNavigator nav = doc.CreateNavigator();
// Compile an xpath expression
XPathExpression expr = nav.Compile("./LOCALCELL_V18/MXPWR");
XPathNodeIterator iterator = nav.Select(expr);
// Iterate on the node set
while (iterator.MoveNext())
{
string s = iterator.Current.Value;
}
When I run this on your XML file (wrapped in a root node) I get:
s = 100
s = 200
s = 300
I would use XLinq:
using System.Xml.Linq;
var xDoc = XDocument.Load("data.xml");
var mxpwrs = xDoc.Descendants("MXPWR");
foreach (var mxpwr in mxpwrs)
{
Console.WriteLine(mxpwr.Value);
}

Categories

Resources