How to check XMLNode is exist or not in Windows Phone - c#

I am writing Windows Phone 8 application, and I am getting XML data from web service,in some response, in my XML document I am getting some "Tags" and in other response I do not getting those tags, so how do I check that XNode is exist or not?
See my XML document below:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Group>
<Id>205647</Id>
<Name>Docs</Name>
</Group>
<Group>
<Id>205648</Id>
<Name>Photos</Name>
</Group>
</root>
Now, in above document, the Descendant "GROUP" is exist in some results and doesn't exist in other results,How do I check that?

Create an extension method like this :
public static string TryGetElementValue(this XElement parentEl, string elementName, string defaultValue = null)
{
var foundEl = parentEl.Element(elementName);
if(foundEl != null)
{
return foundEl.Value;
}
else
{
return defaultValue;
}
}
This approach allows you to keep a clean code with isolating the check of element presence. It also allow you to define a default value, which can be helpful

You could go through all nodes with the XmlTextReader and look for a specific XmlNode Name.
http://www.w3schools.com/xpath/xpath_syntax.asp
Try this snippet with your xml:
XmlDocument doc = new XmlDocument();
doc.Load("your.xml");
//Select the book node with the matching attribute value.
XmlNode nodeToFind;
XmlElement root = doc.DocumentElement;
// Selects all the title elements that have an attribute named group
nodeToFind = root.SelectSingleNode("//title[#group]");
if( nodeToFind != null )
{
// It was found, manipulate it.
}
else
{
// It was not found.
}
Have a look at this too. updating an existing xml file in Windows Phone
Hope it helps!

Related

Reading xml file on some condition

I want to use a xml file which is as below
<?xml version="1.0" encoding="utf-8" ?>
<pages>
<page name="Default.aspx">
<method name="Login_click">
<message code="0" description="this is a test description">
<client code="0000000000" description="this is a description for clent 0000000000" />
</message>
</method>
</page>
</pages>
Now I want to create a function like below
public static string GetAppMessage(string pageName, string methodName, string clientCode, string code)
{
var xmlFile = HttpContext.Current.Server.MapPath("~/App_Data/Theme.xml");
var doc = new XmlDocument();
doc.Load(xmlFile);
if (string.IsNullOrEmpty(clientCode))
{
//go to node who page name to pageName
//and read the vlue
}
else
{
//read for a particular client code
}
}
How can I do this.
Edit 1
Do I need to loop through each node or can I reach to a particular node directly and find the decedent nodes.
like below
foreach (XmlNode chldNode in doc.ChildNodes)
{
....
Instead of XmlDocument you can use XDocument and LINQ to xml:
var xmlFile = HttpContext.Current.Server.MapPath("~/App_Data/Theme.xml");
XDocument xmlDoc = XDocument.Load(xmlFile);
var xmlPage = (from page in xmlDoc.Descendants()
where page.Name.LocalName == "page"
&& page.Attribute("name").Value == pageName
select page).FirstOrDefault();
if (xmlPage != null)
{
//do what you need
}
When you use XmlDocument and you know how the XML-file will look like (I mean you know the names of the nodes where the information is inside) then you could do something like this:
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlElement root = doc["NameOfRootNode"];
if (root != null)
{
//For nodes you just need to bypass to get to another subnode:
XmlNode node = root.SelectSingleNode("nameOfAnotherNode");
//For nodes you actually want to do something with, like read text, attribute etc.
if (node != null && node.SelectSingleNode("nameOfOneMoreNode") != null)
{
var xmlElement = node["nameOfOneMoreNode"];
if (xmlElement != null)
{
//Read from the xmlElement you selected and do something with it...
}
}
//...
}
With SelectSingleNode or SelectNodes you can maneuver to a specific known node and can read the InnerText or an Attribute.
You can use XPath to get <page> element by it's name attribute, for example :
string xpath = "//page[#name='{0}']";
XmlNode page = doc.SelectSingleNode(string.Format(xpath, pageName));
//and read the vlue
Basically, above XPath look for <page> element having name attribute equals pageName parameter.

Reading xml with XmlReader

Here is xml that I want to read
<servers>
<server name=" PIOU PIOU || OPTIMAL" ca="1" continent_code="EU"
country="France" country_code="FR" ip="s1.mymumble.fr"
port="20129" region="" url="http://www.mymumble.fr" />
</servers>
Now when I read it I successfully get the elemnt 'servers' and I can read its innerxml as well i.e the correct node is created. but when I create a node with element 'server' the node is empty.
I guess the reason is the short form of starting and ending element used in the 'server' node.
But my problem is that the xml comes from some remote server and I cannot modify it, so I have to read it the way it is written.
Here is my code to read XML:
List<XmlNode> nodeList = new List<XmlNode>();
XmlDocument doc = new XmlDocument();
while (reader.Read())
{
//keep reading until we see my element
if (reader.Name.Equals("server") && (reader.NodeType == XmlNodeType.Element))
{
XmlNode myNode = doc.ReadNode(reader);
Debug.Log(reader.IsEmptyElement ? "its empty" : "not empty");
//this always prints "its empty"
nodeList.Add(myNode);
}
}
foreach( XmlNode node in nodeList)
{
Debug.Log("child:\t"+node.FirstChild.InnerXml);
}
See the documentation for IsEmptyElement. In particular, this example:
<item num="123"/> (IsEmptyElement is true).
<item num="123"></item> (IsEmptyElement is false, although element content is empty).
Your node is considered empty because it uses the short form. There is no element "content," but there are attributes.
Have you checked the node that you created (i.e. myNode) to see that it contains the attributes?
XmlReader is kind of low level for your needs...
Wouldn't it be easier to parse your XML with Linq2Xml?
var xmlStr = #"<servers>
<server name="" PIOU PIOU || OPTIMAL"" ca=""1"" continent_code=""EU""
country=""France"" country_code=""FR"" ip=""s1.mymumble.fr""
port=""20129"" region="""" url=""http://www.mymumble.fr"" />
</servers>";
var doc = XDocument.Parse(xmlStr);
var servers = doc.Root.Elements("server")
.Select(e => new{
name = (string)e.Attribute("name"),
ca = (int)e.Attribute("ca"),
country = (string)e.Attribute("country")
//etc...
});
XmlDocument has method called "GetNodes", that will help you.

How to get data from an XML File in C# using XMLDocument class?

Good Evening All, and happy weekend!.
I have been trying all day to understand how to parse my simple XML file so I can understand it enough to write a personal project I want to work on.
I have been reading articles on this site and others but cannot get past where I am :(
My XML Document is ...
<XML>
<User>
<ID>123456789</ID>
<Device>My PC</Device>
</User>
<History>
<CreationTime>27 June 2013</CreationTime>
<UpdatedTime>29 June 2013</UpdatedTime>
<LastUsage>30 June 2013</LastUsage>
<UsageCount>103</UsageCount>
</History>
<Configuration>
<Name>Test Item</Name>
<Details>READ ME</Details>
<Enabled>true</Enabled>
</Configuration>
</XML>
I am trying to get the value in the details element (READ ME). Below is my code
// Start Logging Progress
Console.WriteLine("Test Application - XML Parsing and Creating");
Console.ReadKey();
// Load XML Document
XmlDocument MyDoc = new XmlDocument(); MyDoc.Load(#"E:\MyXML.XML");
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details");
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.Value));
// Pause
Console.ReadKey();
My console application is running and outputing "Target: " but not giving me the detail within the element.
Can somebody see why this is happening, and perhaps give me advice if I am completely off the wheel? I have no previous knowledge in reading XML files; hence where I am now :)
Thanks! Tom
With the your XPATH expression
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details");
your are selection an element so the type of the MyNode will be XmlElement but the Value of an XmlElement is always null (see on MSDN) so you need to use XmlElement.InnerText or XmlElement.InnerXml isntead.
So the changed your code to
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.InnerText));
Or you can select the content of an element with using the XPATH text() function, in this case MyNode will be XmlText where you get its value with Value:
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details/text()");
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.Value));
As a sidenote if you are anyway learning XML manipulation in C# you should check out LINQ to XML which is another/newer way to working with XML in C#.
Just for interest, a little-known "simple" syntax is this:
XmlDocument myDoc = new XmlDocument();
myDoc.Load(#"D:\MyXML.XML");
string details = myDoc["XML"]["Configuration"]["Details"].InnerText;
Note that this (and the XPath approach) could go pop if your XML doesn't conform to the structure you're expecting, so you'd ideally put some validation in there as well.
U can use Xpath library for that (u must include "System.Xml.XPath"):
XmlDocument document = new XmlDocument();
document.Load("MyXml.xml");
XPathNavigator navigator = document.CreateNavigator();
foreach (XPathNavigator nav in navigator.Select("//Details"))
{
Console.WriteLine(nav.Value);
}
the above code iterate over every node called (Details) extracting information and print it.
If you want to retrieve a particular value from an XML file
XmlDocument _LocalInfo_Xml = new XmlDocument();
_LocalInfo_Xml.Load(fileName);
XmlElement _XmlElement;
_XmlElement = _LocalInfo_Xml.GetElementsByTagName("UserId")[0] as XmlElement;
string Value = _XmlElement.InnerText;
Value contains the text value

Adding XML attribute to an element

Looking to add an attribute to an existing xml element <D_COMMS>, not replace the existing attribute just add it to the beginning.
This is the XML
<OUTPUT version="2.0">
<RESPONSE>
<DATA id="17fb13cca6c5463597fdf340c044069f">
<![CDATA[<ID> jdfkldklfjdkl</ID><D_COMMS>ON this date...</D_COMMS>]]>
</DATA>
</RESPONSE>
This XML is the result of a HTTPWebResponse so this is what the XMl looks like when it comes back to me and I need to add a value to the D_COMMS element and send it back.Tried something like this to look for the descendant DATA and add it that way.
var addelement = doc.Descendants("DATA").First();
addelement.Add(XElement("D_COMMS","On this date we said"));
A better one to set attribute is in here Adding attributes to an XML node
XmlElement id = doc.CreateElement("id");
id.SetAttribute("userName", "Tushar");
You can find the DATA node and add an attribute as follows:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList dataNodes = doc.GetElementsByTagName("DATA");
if (dataNodes != null && dataNodes.Count > 1)
{
dataNodes[0].Attributes.Append(doc.CreateAttribute("D_COMMS", "On this date we said"));
}

Modify Node Value C# with ID

Here is my XML :
<?xml version="1.0" encoding="utf-8" ?>
<Selection>
<ID>1</ID>
<Nom>Name 1</Nom>
<DateReference>0</DateReference>
<PrefixeMedia>Department</PrefixeMedia>
<FormatExport>1630</FormatExport>
<TraceAuto>Oui</TraceAuto>
<SubID></SubID>
</Selection>
<Selection>
<ID>2</ID>
<Nom>Name 1</Nom>
<DateReference>0</DateReference>
<PrefixeMedia>Department</PrefixeMedia>
<FormatExport>1630</FormatExport>
<TraceAuto>1</TraceAuto>
<SubID>1</SubID>
</Selection>
My problem is I would like to modify for example the node content of <Nom>Name 1</Nom> which is located in <Selection></Selection> which have <ID>1</ID> (Search by ID)
I'm using XElement and XDocument to do simple search but I need some help to solve this problem above. (Developpment on SilverLight
Best Regards.
Another way to do this is using XmlDocument:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"\path\to\file.xml");
// Select the <nom> node under the <Selection> node which has <ID> of '1'
XmlNode name = xmlDoc.SelectSingleNode("/Selection[ID='1']/Nom");
// Modify the value of the node
name.InnerText = "New Name 1";
// Save the XML document
xmlDoc.Save(#"\path\to\file.xml");
If you don't know how to get at the correct <Nom> node to update, the trick is to first select a <Selection> node that contains the correct <ID> node, then you can get that <Nom> node.
Something like:
XElement tree = <your XML>;
XElement selection = tree.Descendants("Selection")
.Where(n => n.Descendants("ID").First().Value == "1") // search for <ID>1</ID>
.FirstOrDefault();
if (selection != null)
{
XElement nom = selection.Descendants("Nom").First();
nom.Value = "Name one";
}
Note 1: By using Descendants("ID").First() I expect every Selection node to contain an ID node.
Note 2: And every Selection node contains a Nom node
Note 3: Now you still have to store the whole XML, if that's what you need.

Categories

Resources