how to parsing XML file - c#

I have a file in that format
<?xml version="1.0" encoding="UTF-8"?>
<AMG>
<Include File="..."/> <!-- comment -->
<Include File="...."/> <!-- comment -->
<AMGmers Name="Auto">
<Array Type="move" Name="move_name"/>
</AMGmers>
<AMGmers Name="Black" Parent="Auto">
<Attr Type="Color" Name="auto_Params"/>
</AMGmers>
<!-- comment -->
</AMG>
I have to get all name from <AMGmers>, and I have to check availability Parent.
I was trying to do so
XmlDocument doc1 = new XmlDocument();
doc1.Load("test.xml");
XmlNodeList elemList1 = doc1.GetElementsByTagName("Name");
Please help me understand.

Since <AMG> is the root node and <AMGmers> tags are inside <AMG>, you can get all <AMGmers> tags using this syntax
XmlNodeList elemList1 = doc1.SelectNodes("AMG/AMGmers");
I assume you want to get the value of Name attribute from all <AMGmers> tags and check whether each <AMGmers> tag has Parent attribute, so this code should work
foreach (XmlNode node in elemList1)
{
if (node.Attributes["Name"] != null)
{
string name = node.Attributes["Name"].Value;
// do whatever you want with name
}
if (node.Attributes["Parent"] != null)
{
// logic when Parent attribute is present
// node.Attributes["Parent"].Value is the value of Parent attribute
}
else
{
// logic when Parent attribute isn't present
}
}
EDIT
If you want to get the <Array> nodes inside <AMGmers>, you can do so as below
foreach (XmlNode node in elemList1)
{
XmlNodeList arrayNodes = node.SelectNodes("Array");
foreach (XmlNode arrayNode in arrayNodes)
{
if (arrayNode.Attributes["Type"] != null)
{
// logic when Type attribute is present
// arrayNode.Attributes["Type"].Value is the value of Type attribute
}
}
}
EDIT 2
If you want to enumerate all nodes inside <AMGmers>, you can do so as below
foreach (XmlNode node in elemList1)
{
foreach (XmlNode childNode in node.ChildNodes)
{
// do whatever you want with childNode
}
}

Related

Empty Child and another child attribute vlaues

Hi All: Could you please tell me what is the mistake in gettting the child & child2 attribute values?
I'm getting the valu of the node attribute but not for the childs nodes.
Overall i need to get Name value from products, Visibile value from the element Visibilities, and Price value from elment Prices.
Code:
XmlDocument doc = new XmlDocument();
doc.Load("Prices.txt");
XmlNodeList nodes = doc.GetElementsByTagName("RetroPrintProduct");
foreach (XmlNode node in nodes)
{
Console.WriteLine("Name={0} ", node.Attributes["Name"].Value);
foreach (XmlNode child in node.SelectNodes("ProductVisibility "))
{
Console.WriteLine("Visible={0}", child.Attributes["Visible"].Value);
foreach (XmlNode child2 in child.SelectNodes("Prices"))
{
Console.WriteLine("Price={0}", child2.Attributes["Price"].Value);
}
}
}
XML file:
<Item>
<RetroPrintProduct Nino123="d89e280b-c8d5-4da2-87da-36e4a57e2867" Nino1="2022ProfileProducts.RetroPrintProduct" Sys_Index="UpdateOnly" DefaultIconName="RetroPrints_10x8x2_R_Metallic.png" DefaultOutputProfileName="Nino" DefaultOutputProfileTypeFullName="2022Profile" Name="Item Retro">
<ShippingMethodPrices Index="Replace" />
<Visibilities Index="Replace" />
</RetroPrintProduct>
<RetroPrintProduct Nino123="67d1577d-7baf-4b3f-a9fb-9d52404e45f4" Nino1="2022ProfileProducts.RetroPrintProduct" Sys_Index="UpdateOnly" DefaultIconName="RetroPrints_10x8x2_S_Normal.png" DefaultOutputProfileName="Nino" DefaultOutputProfileTypeFullName="2022Profile" Name="Item 2 Retro">
<ShippingMethodPrices Index="Replace" />
<Visibilities Index="Replace">
<ProductVisibility Nino123="cc0096e0-d964-4e45-93f7-9258ddee148d" Sys_GlobalUniqueId="cc0096e0-d964-4e45-93f7-9258ddee148d" Sys_ReplicationId="39f43856-a16f-4555-b519-ccf71b97ee58" Nino1="2022.ProductVisibility" Activated="True" Noprices="False" PhotoSource="EndUserPhotos" BackgroundColor="Default" Icon="" Image="" IsUnusableByLicense="False" MaxDate="2999-12-31" MinDate="1900-01-01" Name="" Object="Visible" Visible="True" ProductLibrary="" ReplicationId="39f43856-a16f-4555-b519-ccf71b97ee58" SysCode="">
<Prices Index="Replace">
<ProductPrice Nino123="4ca2658e-3e07-4636-b33f-d87fb021288a" Sys_GlobalUniqueId="4ca2658e-3e07-4636-b33f-d87fb021288a" Sys_ReplicationId="3e75b8f4-d1b6-41fe-be9e-d2858caf6eb9" Nino1="2022.ProductPrice" FixFee="0" ServiceFee="0" Mode="Replace" FromQuantity="1" Price="0.5" ProductPriceType="PerPageQuantity" ProductLibrary="" ReplicationId="3e75b8f4-d1b6-41fe-be9e-d2858caf6eb9" SysCode="" />
</Prices>
</ProductVisibility>
</Visibilities>
</RetroPrintProduct>
</Item>
It looks like you're missing some nesting when searching through the nodes. ProductVisibility is under Visibilites, not RetroPrintProduct, and Price is an attribute of ProductPrice, not Prices.
Something like this should do the trick (note that I named the nodes in code to match the xml names to make it easier to remember which child is which):
XmlDocument doc = new XmlDocument();
doc.Load(#"c:\temp\Prices.xml");
XmlNodeList retroPrintProducts = doc.GetElementsByTagName("RetroPrintProduct");
foreach (XmlNode retroPrintProduct in retroPrintProducts)
{
Console.WriteLine("Name={0} ", retroPrintProduct.Attributes["Name"].Value);
foreach (XmlNode visibility in retroPrintProduct.SelectNodes("Visibilities"))
{
foreach (XmlNode productVisibilty in visibility.SelectNodes("ProductVisibility"))
{
Console.WriteLine("Visible={0}", productVisibilty.Attributes["Visible"].Value);
foreach (XmlNode price in productVisibilty.SelectNodes("Prices"))
{
foreach (XmlNode productPrice in price.SelectNodes("ProductPrice"))
{
Console.WriteLine("Price={0}", productPrice.Attributes["Price"].Value);
}
}
}
}
}

How to get "elements" in node

I trying to get "elements" from node and show in MessageBox
My XML: <Item Name="Test" Count="5"/>
Elements:
Name
Count
My Code:
XmlNodeList xmlNodes = xmlDocument.SelectNodes("Item");
foreach (XmlNode xmlNode in xmlNodes)
{
MessageBox.Show(xmlNode.InnerText);
}
But I do not know how to do this
You need to use Attributes. Check my solution
XmlNodeList xmlNodes = xmlDocument.SelectNodes("Item");
foreach (XmlNode xmlNode in xmlNodes)
{
foreach (XmlAttribute attr in xmlNodes.Attributes)
{
MessageBox.Show($"Attribute Name is {attr.Name} and Value is {attr.Value}");
}
}

read child nodes xml

Here is my xml which i am trying to read.
<VacancyList xmlns="urn:abc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" generated="2016-04-20T11:42:47" xsi:schemaLocation="http://www.abc.in/dtd/vacancy-list.xsd">
<Vacancy id="1619993" date_start="2016-04-15" date_end="2016-04-22" reference_number="">
<Versions>
<Version language="nb">
<Title>Marketing Specialist</Title>
<TitleHeading/>
<Location>CXCXC</Location>
<Engagement/>
<DailyHours/>
<Region>
<County id="11">sds</County>
<County id="1">zxzx</County>
</Country>
</Region>
<Categories>
<Item type="position-type" id="3909">sER</Item>
<Item type="duration" id="contract">ss</Item>
<Item type="extent" id="fulltime">sd</Item>
<Item type="operating-time" id="day">s</Item>
</Categories>
</Version>
</Versions>
</Vacancy>
</VacancyList>
I want to read node location so wrote below code
XmlDocument xd = new XmlDocument();
xd.Load("https://abc.in/list.xml");
XmlNamespaceManager ns = new XmlNamespaceManager(xd.NameTable);
ns.AddNamespace("msbld", "urn:abc");
XmlNodeList nodelist = xd.SelectNodes("//msbld:VacancyList", ns);
if (nodelist != null)
foreach (XmlNode node in nodelist)
{
XmlNode nodelist1 = node.SelectSingleNode("Vacancy");
if (nodelist1 != null)
foreach (XmlNode node1 in nodelist1)
{
var k = node1.Attributes.GetNamedItem("Location").Value;
}
}
But i dont get anything in variable "node1". How to fix this?
Also is there any better solution for this?
Update1
i modified code but i only get node Title. cant get others inside Version node like Location.
if (nodelist != null)
foreach (XmlNode node in nodelist)
{
XmlNode nodelist1 = node.SelectSingleNode("//msbld:Vacancy/msbld:Versions",ns);
if (nodelist1 != null) {
XmlNode nodelist2 = nodelist1.SelectSingleNode("//msbld:Version", ns);
foreach (XmlNode node3Node in nodelist2)
{
var k = node3Node.Attributes.GetNamedItem("Location").Value;
}
}
}
xmlns="urn:abc" is a default namespace. Notice that descendant elements without prefix inherits ancestor's default namespace implicitly. You need to use the same prefix that references default namespace URI for acessing Vacancy and Location as well :
XmlNode nodelist1 = node.SelectSingleNode("msbld:Vacancy", ns);
Your updated code introduces an entirely different problem; / at the beginning of a path expression will always reference document element, unless you explicitly set the context to current active context by using . before /, for example :
XmlNode nodelist1 = node.SelectSingleNode(".//msbld:Vacancy/msbld:Versions",ns);
If you only need the Location element then you can do it like this:
var doc = XElement.Load("path/to/file");
var location = doc.Descendants
.FirstOrDefault(e => e.Name.LocalName == "Location"));

if exist on an XML node in XmlNodeList C#

How can i check if a node exists in an XmlNodeList? I have populated a list, and i need to query out specific values. this is how I am doing that.
var xList = xelRoot.SelectNodes("aaa/bbb/ccc/ddd/eee/fff/ggg/hhh");
foreach (XmlNode node in xList)
{
serviceVal = node["service"].InnerText.ToString();
}
there are cases where the service node does not exist. and when that happens I get the error "Object reference is not set to instance of an object".
is there a way to return a string value if the node does not exist?
here is a sample of the xml. notice that rule 1 does not have a service node
<entry name="aaa">
<from>any</from>
<to>any</to>
<source>any</source>
<destination>any</destination>
<source-user>any</source-user>
<category>any</category>
<service>any</service>
</entry>
<entry name="Rule 1">
<from>any</from>
<to>any</to>
<source>any</source>
<destination>any</destination>
<source-user>any</source-user>
<category>any</category>
</entry>
Simply test for null...
XmlNode subNode;
foreach (XmlNode node in xList)
{
subNode = node["service"];
if (subNode != null)
{
serviceVal = subNode.InnerText;
}
else
{
serviceVal = string.Empty;
}
}

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.

Categories

Resources