Finding inner text value from XML file - c#

When I write this code, I get only the parent tag value. I want to get their childnodes value also, please tell me about this.
XmlDocument DOC = new XmlDocument();
DOC.RemoveAll();
DOC.Load("C:\\Users\\DIGITEL EYE SYSTEM\\Desktop\\response.xml");
foreach (XmlNode AllNodes in ParentNode)
{
Project.Name = AllNodes["Name"].InnerText;
if (AllNodes.ChildNodes == DOC.GetElementsByTagName("AppBuilderForms"))
{
// Project.Forms = DOC.GetElementsByTagName("");
// String sb = AllNodes["Forms"].InnerText;
}
else if (AllNodes.ChildNodes==DOC.GetElementsByTagName("CheckMarkObject"))
{
checkmark.Name = AllNodes["Name"].InnerText;
checkmark.Label = AllNodes["Label"].InnerText;
// checkmark.IsChecked = AllNodes["IsChecked"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("DateTimeObject"))
{
DateTime.Name = AllNodes["Name"].InnerText;
DateTime.Label = AllNodes["Label"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("LocationObject"))
{
Location.Name = AllNodes["Name"].InnerText;
Location.Label = AllNodes["Label"].InnerText;
Location.Longitude = AllNodes["Longitude"].InnerText;
Location.Latitude = AllNodes["Latitude"].InnerText;
}
else if (ParentNode==DOC.GetElementsByTagName("SwitchObject"))
{
Switch.Name = AllNodes["Name"].InnerText;
Switch.Label = AllNodes["Label"].InnerText;
// Switch.IsChecked =AllNodes["IsChecked"].InnerText;
}
else if(ParentNode==DOC.GetElementsByTagName("TextViewObject"))
{
TextView.Name = AllNodes["Name"].InnerText;
TextView.Value = AllNodes["Value"].InnerText;
}
else if (ParentNode ==DOC.GetElementsByTagName("TextFieldObject"))
{
TextField.Name = AllNodes["Name"].InnerText;
TextField.Value = AllNodes["Value"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("PhotoPickerObject"))
{
PhotoPicker.Name = AllNodes["Name"].InnerText;
PhotoPicker.Label = AllNodes["Label"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("SpinWheelPickerObject"))
{
SpinWheelPicker.Name = AllNodes["Name"].InnerText;
SpinWheelPicker.Label = AllNodes["Label"].InnerText;
// SpinWheelPicker.Columns = AllNodes["Columns"].InnerText;
}
}

var xdoc = XDocument.Load(#"C:\Users\DIGITEL EYE SYSTEM\Desktop\response.xml");
var allElements = xdoc.Root.Elements();
foreach (string element in allElements)
{
//TODO add logic
}
First we'll load up the xml into a XDocument (needs .Net 3.5),
nothing odd going on here.
Second we'll select the root node and ALL
the elements under the root into a IEnumrable. You can add a filter here in the Elements() method.
Third we'll start iterating over the elements in our IEnumerable and implicitly
cast them to a string, this is a operator in the LINQ to XML lib
that just returns the XElement.Value (so if you think that's more
readable or need the whole Element for some other reason write
that! I.E XElement element in allElements)
Don't know how to do it in XmlDocument, I've totally forgotten, hopefully this might help you in case you'll go down that path (pun intended).

Related

A fast way to compare two XML files and create another one with differences

My friend wants to upload only product differences to his web shop. So my idea is to compare XML files and extract only changes. Thus I've created this:
Part of XML file (note that this XML have more elements, but I've excluded them):
<?xml version="1.0" encoding="UTF-8"?>
<artikli>
<artikal>
<id>1039282</id>
<sifra>42640</sifra>
<naziv><![CDATA[Bluetooth zvucnik za tablet IYIGLE X7 crni]]></naziv>
</artikal>
<artikal>
<id>1048331</id>
<sifra>48888</sifra>
<naziv><![CDATA[Bluetooth zvucnik REMAX RB-M15 crni]]></naziv>
</artikal>
</artikli>
C# script
static IEnumerable<XElement> StreamRootChildDoc(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
reader.MoveToContent();
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "artikal")
{
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
else
{
reader.Read();
}
}
}
}
void ProcessFiles()
{
try
{
IEnumerable<XElement> posle = from el in StreamRootChildDoc(#"lisic2.xml")
select el;
IEnumerable<XElement> pre = from el in StreamRootChildDoc(#"lisic1.xml")
select el;
XmlDocument doc = new XmlDocument();
//(1) the xml declaration is recommended, but not mandatory
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
//(2) string.Empty makes cleaner code
XmlElement element1 = doc.CreateElement(string.Empty, "artikli", string.Empty);
doc.AppendChild(element1);
int count_files = 0;
foreach (XElement node_posle in posle)
{
count_files++;
var node_pre = pre.First(child => child.Element("id").Value == node_posle.Element("id").Value);
if (node_pre != null)
{
string pre_Value = node_pre.Value.Replace("\t", ""); ;
string posle_Value = node_posle.Value.Replace("\t", ""); ;
if (pre_Value != posle_Value)
{
var reader = node_posle.CreateReader();
reader.MoveToContent();
XmlElement element2 = doc.CreateElement(string.Empty, "artikal", reader.ReadInnerXml());
element1.AppendChild(element2);
}
}
}
doc.Save("document.xml");
}
finally
{
}
}
This works but after 10000 passed records the speed is 18 records per second, after 14000 - 12 records/sec. Is there any other approach to speed this up?
UPDATE
Now, I will try to move faster to the corresponding ID of checked XML.
One way to do it is with XmlDocument, just because the XML is small (22000 products) it is possible to use it.
void ProcessXMLDocument()
{
SetControlEnabled(btStart, false);
Stopwatch sw = new Stopwatch();
sw.Start();
try
{
XmlDocument sada = new XmlDocument();
sada.Load(tbPathSada.Text);
XmlDocument pre = new XmlDocument();
pre.Load(tbPathOdPre.Text);
XmlDocument doc = new XmlDocument();
//(1) the xml declaration is recommended, but not mandatory
XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmlDeclaration, root);
//(2) string.Empty makes cleaner code
XmlElement element1 = doc.CreateElement(string.Empty, "artikli", string.Empty);
doc.AppendChild(element1);
root = sada.DocumentElement;
XmlNodeList nodes = root.SelectNodes("artikal");
int count_files = 0;
foreach (XmlNode nodeSada in nodes)
{
count_files++;
try
{
SetControlText(lbBlokova, count_files.ToString());
TimeSpan elapsed = sw.Elapsed;
var files_per_sec = Math.Floor((double)count_files / (double)elapsed.TotalSeconds);
SetControlText(lbPerSecond, files_per_sec.ToString());
SetControlText(lbTime, elapsed.ToString(#"hh\:mm\:ss"));
}
catch (Exception ex2)
{
}
var idSada = nodeSada.SelectSingleNode("id").InnerText.Trim();
var nodePre = pre.DocumentElement.SelectSingleNode("artikal[id='" + idSada + "']");
if (nodePre != null)
{
string pre_Value = nodePre.InnerXml.Replace("\t", ""); ;
string posle_Value = nodeSada.InnerXml.Replace("\t", ""); ;
if (pre_Value != posle_Value)
{
XmlNode importNode = doc.ImportNode(nodeSada, true);
element1.AppendChild(importNode);
}
}
else
{
XmlNode importNode = doc.ImportNode(nodeSada, true);
element1.AppendChild(importNode);
}
}
doc.Save("razlika.xml");
}
finally
{
sw.Stop();
SetControlEnabled(btStart, true);
}
}
This way I've managed to improve #10000 records => 140 rec/sec and #14000 => 104 rec/sec

How can I get the value from XML return boolean value?

I want to make a funtion to input value (funName) and check XML file attribute (FunName) then output XML file attribute (isEnable) boolean true or false
How can I modify this code?
My XML file
<itema>
<itemb FunName="ABC" isEnable="true"></itemb>
<itemb FunName="DEF" isEnable="false"></itemb>
</itema>
My Code
public bool FunEnable(string funName , string isEnable)
{
bool result = true;
XmlDocument xDL = new XmlDocument();
xDL.Load("C://XMLFile2.xml"); //Load XML file
XmlNode xSingleNode = xDL.SelectSingleNode("//itemb");
XmlAttributeCollection xAT = xSingleNode.Attributes; //read all Node attribute
for (int i = 0; i < xAT.Count; i++)
{
if (xAT.Item(i).Name == "isEnable")
{
Console.WriteLine(xAT.Item(i).Value); //read we want attribute content
}
}
return result;
}
Thanks a lot
Well you can try this :
public static bool FunEnable(string funNam)
{
bool result = true;
XmlDocument xDL = new XmlDocument();
xDL.Load(#"C:/XMLFile2.xml"); //Load XML file
XmlNodeList nodeList = xDL.SelectNodes("//itemb");
foreach (XmlNode node in nodeList)
{
if (node.Attributes["FunName"].Value.Equals(funNam))
{
result = Convert.ToBoolean(node.Attributes["isEnable"].Value);
break;
}
}
Console.WriteLine("with funName = "+ funNam +" isEnable equal to : " + result);
return result;
}
Output
with funName = ABC isEnable equal to : True
This is fairly trivial using LINQ to XML. You can load the document using XDocument.Load and then get your isEnable value like so:
var result = doc.Descendants("itemb")
.Where(e => (string)e.Attribute("FunName") == "ABC")
.Select(e => (bool)e.Attribute("isEnable"))
.Single();
You can see a working demo here: https://dotnetfiddle.net/MYTOl6
var xDoc = XDocument.Load(path);
bool result = (from itemb in xDoc.Descendants("itemb")
where itemb.Attribute("FunName").Value == funcName
select itemb.Attribute("isEnable").Value == "true")
.FirstOrDefault();
Well, I prefer Linq to XML..
Maybe that one works:
public bool FunEnable(string funName, string isEnable)
{
bool result = true;
XDocument xDL = XDocument.Load("C://XMLFile2.xml");
var xSingleNode = from node in xDL.Descendants("itemb")
where node.Attribute("FunName").Value == funName
select node;
if(xSingleNode.Count() > 0)
{
result = xSingleNode.ElementAt(0).Attribute("isEnable").Value == "true";
//If there is at least one node with the given name, result is set to the first nodes "isEnable"-value
}
return result;
}

Issue with reading multiple xml nodes instead of one

The XML bills usually have one Node that is returned and parsed. We have come across an issue where an XML bill had multiple Nodes. Since the code is not set up to handle that, the customer ended up with an incorrect bill.
This is the code I have that goes through the bill list. If it comes back with a node then it parses the information from the xml.
var response = new List<CustomerBill>();
try
{
foreach (GetBillForCAResponse eBillResponse in eBillResponseList)
{
var statementDetailsResponse = GetStatementDetails(
new GetStatementDetailsRequest
{
BatchId = eBillResponse.BatchId,
CustomerAccountId = eBillResponse.CA.ToString("000000000"),
StatementId = eBillResponse.CAS_NUM.ToString("0000")
});
string xmlBill = statementDetailsResponse.StatementAsXML.ToString();
var document = new XmlDocument();
document.LoadXml(xmlBill);
var saDetailedPageNode = XmlBillParser.GetDetailPageSectionBySa(requestSa, xmlBill);
if (saDetailedPageNode == null) continue;
var customerBill = new CustomerBill();
customerBill.IsSurepay = XmlBillParser.GetSurepayFlagFromBill(document);
customerBill.ServiceAddress = XmlBillParser.GetServiceAddress(requestSa, document);
customerBill.monthName = XmlBillParser.GetnillStatementDate(requestSa, xmlBill);
customerBill.EqCurlPlanBal = XmlBillParser.getEqualizerCurrentPlanBalance(document);
customerBill.EqPymntDue = XmlBillParser.getEqualizerPaymentDue(document);
customerBill.Service = GetServiceAccountUsageAndBillingDetail(requestSa, xmlBill, saDetailedPageNode);
response.Add(customerBill);
}
}
catch (Exception ex)
{
trace.Write(new InvalidOperationException(requestSa, ex));
}
return response;
}
Here is the method that checks if there is a node in the XML. I have changed the code so that is returns all the nodes. I had to change the type xmlNode to xmlNodeList because now its returning a collection of nodes. ****This is whats causing all the problems in my code in other places.***
public static xmlNode GetDetailPageSectionBySa(string sa, string statementXml)
{
XmlDocument document = new XmlDocument();
document.LoadXml(statementXml);
string requestSa = sa.PadLeft(9, '0');
string xpath = String.Format("//Para[IRBILGP_SA_SAA_ID_PRINT.SERVICE.ACCOUNT.STATMENT='{0}S{1}']/..", requestSa.Substring(0, 4), requestSa.Substring(4));
return document.SelectNodes(xpath);
//var nodes = document.SelectNodes(xpath);
// if(nodes.Count > 0) return nodes[nodes.Count - 1];
//if(!SaExistInBill(requestSa, statementXml)) return null;
//var node = GetDetailPageSectionByBillPrisminfoIndex(sa, statementXml);
//if (node != null) return node;
//return null;
}
So returning back to where it is called.. im getting an invalid arguement here
customerBill.Service = GetServiceAccountUsageAndBillingDetail(requestSA, xmlBill, saDetailedPageNode); because the parameter saDetailedPageNode is xmlNodeList now when it is expecting of type xmlNode. if i go to the method private static ServiceAddressBillDetail GetServiceAccountUsageAndBillingDetail(string requestSA, string xmlBill, XmlNode detailPageNode) which i added at the end of this code so you could see. If I change the parameter XmlNode detailPageNode to XmlNodeList detailPageNode which I have to do to fix the invalid arguement above, I get that detailPageNode.SelectNodes becomes invalid because xmlNodeList does not have SelectNodes as an extension method. I use this extention method a lot through this method. So I am getting a lot of errors.
var saDetailedPageNode = XmlBillParser.GetDetailPageSectionBySa(requestSa, xmlBill);
if (saDetailedPageNode == null) continue;
var customerBill = new CustomerBill();
customerBill.IsSurepay = XmlBillParser.GetSurepayFlagFromBill(document);
customerBill.ServiceAddress = XmlBillParser.GetServiceAddress(requestSa, document);
customerBill.monthName = XmlBillParser.GetnillStatementDate(requestSa, xmlBill);
customerBill.EqCurlPlanBal = XmlBillParser.getEqualizerCurrentPlanBalance(document);
customerBill.EqPymntDue = XmlBillParser.getEqualizerPaymentDue(document);
customerBill.Service = GetServiceAccountUsageAndBillingDetail(requestSa, xmlBill, saDetailedPageNode);
response.Add(customerBill);
}
}
catch (Exception ex)
{
trace.Write(new InvalidOperationException(requestSa, ex));
}
return response;
}
private static ServiceAddressBillDetail GetServiceAccountUsageAndBillingDetail(string requestSA, string xmlBill, XmlNode detailPageNode)
{
var saBillDetail = new ServiceAddressBillDetail();
saBillDetail.UsageServiceName = requestSA;
var meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_b");
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_a");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_b");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_a");
}
var demandXMLNodes = detailPageNode.SelectNodes("Usage_kW_Total_Bold");
How can i fix my invalid arguments so that I can use xmlNodeList instead of xmlNode? is there a way to convert or cast? or is there another xml object I can use?
Since I am now returning multiple nodes. I know that I will need to loop through the customerBill portion. How can I do that without creating a new bill for every node? All the nodes in one xml need to be included in one bill.
From the code you've provided, the only part that needs to account for your refactor to XmlNodeList is GetServiceAccountUsageAndBillingDetail(), so you have two options:
Update GetServiceAccountUsageAndBillingDetail() to take in an XmlNodeList parameter instead and aggregate values inside that method to come up with your final ServiceAddressBillDetail object.
Loop through your XmlNode objects in the XmlNodeList and reconcile the different ServiceAddressBillDetail objects yourself.
Without details on what ServiceAddressBillDetail, I can only guess as to which is better, but I'd suggest using the first option.
private static ServiceAddressBillDetail GetServiceAccountUsageAndBillingDetail(
string requestSA,
string xmlBill,
XmlNodeList detailPageNodes)
{
var saBillDetail = new ServiceAddressBillDetail();
saBillDetail.UsageServiceName = requestSA;
foreach(XmlNode detailPageNode in detailPageNodes)
{
var meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_b");
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("Usage_kWh_a");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_b");
}
if (meterReadEndXMLNodes.Count == 0)
{
meterReadEndXMLNodes = detailPageNode.SelectNodes("APSElec_kWh_a");
}
var demandXMLNodes = detailPageNode.SelectNodes("Usage_kW_Total_Bold");
//Whatever comes next
}
}
Assuming ServiceAddressBillDetail has properties for "usage" you could simply add the appropriate values from each detailPageNode to the saBillDetail object.
It's hard to see what is going on but this may be the problem;
string xpath = String.Format("//Para..
The "//" will search in the entire document, but you probably want to search for descendent elements.
Here's some code to deal with a similar problem;
XmlNodeList staffNodes = resultXML.SelectNodes("//staff");
List<TempStaff> tempStaffs = staffNodes
.Cast<XmlNode>()
.Select(
i =>
new TempStaff()
{
StaffId = i.SelectSingleNode("id").InnerText,
Forename = i.SelectSingleNode("forename").InnerText,
Surname = i.SelectSingleNode("surname").InnerText,
}
).ToList();
My XML looks like
<staff><forename>asdf</forename><surname>ddsf</surname><id>123</id>... </staff>
<staff><forename>asdfas</forename><surname>asffdf</surname><id>456</id>...</staff>

how to parse XML using XmlReader along with their closing tags?

Consider the following XML which I have to parse.
<root>
<item>
<itemId>001</itemId>
<itemName>test 1</itemName>
<description/>
</item>
</root>
I have to parse each of its tag and store it into a table as follows:
TAG_NAME TAG_VALUE IsContainer
------------ -------------- -----------
root null true
item null true
itemId 001 false
itemName test 1 false
description null false
/item null true
/root null true
Now to get this done, I am using XmlReader as this allows us to parse each & every node.
I am doing it as follows:
I created the following class to contain each tag's data
public class XmlTag
{
public string XML_TAG { get; set; }
public string XML_VALUE { get; set; }
public bool IsContainer { get; set; }
}
I am trying to get the list of tags(including closing ones) as follows:
private static List<XmlTag> ParseXml(string path)
{
var tags = new List<XmlTag>();
using (var reader = XmlReader.Create(path))
{
while (reader.Read())
{
var tag = new XmlTag();
bool shouldAdd = false;
switch (reader.NodeType)
{
case XmlNodeType.Element:
shouldAdd = true;
tag.XML_TAG = reader.Name;
//How do I get the VALUE of current reader?
//How do I determine if the current node contains children nodes to set IsContainer property of XmlTag object?
break;
case XmlNodeType.EndElement:
shouldAdd = true;
tag.XML_TAG = string.Format("/{0}", reader.Name);
tag.XML_VALUE = null;
//How do I determine if the current closing node belongs to a node which had children.. like ROOT or ITEM in above example?
break;
}
if(shouldAdd)
tags.Add(tag);
}
}
return tags;
}
but I am having difficulty determining the following:
How to determine if current ELEMENT contains children XML nodes? To set IsContainer property.
How to get the value of current node value if it is of type XmlNodeType.Element
Edit:
I have tried to use LINQ to XML as follows:
var xdoc = XDocument.Load(#"SampleItem.xml");
var tags = (from t in xdoc.Descendants()
select new XmlTag
{
XML_TAG = t.Name.ToString(),
ML_VALUE = t.HasElements ? null : t.Value,
IsContainer = t.HasElements
}).ToList();
This gives me the XML tags and their values but this does not give me ALL the tags including the closing ones. That's why I decided to try XmlReader. But If I have missed anything in LINQ to XML example, please correct me.
First of all, as noted by Jon Skeet in the comments you should probably consider using other tools, like XmlDocument possibly with LINQ to XML (EDIT: an example with XmlDocument follows).
Having said that, here is the simplest solution for what you have currently (note that it's not the cleanest possible code, and it doesn't have much validation):
private static List<XmlTag> ParseElement(XmlReader reader, XmlTag element)
{
var result = new List<XmlTag>() { element };
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
element.IsContainer = true;
var newTag = new XmlTag() { XML_TAG = reader.Name };
if (reader.IsEmptyElement)
{
result.Add(newTag);
}
else
{
result.AddRange(ParseElement(reader, newTag));
}
break;
case XmlNodeType.Text:
element.XML_VALUE = reader.Value;
break;
case XmlNodeType.EndElement:
if (reader.Name == element.XML_TAG)
{
result.Add(new XmlTag()
{
XML_TAG = string.Format("/{0}", reader.Name),
IsContainer = element.IsContainer
});
}
return result;
}
}
return result;
}
private static List<XmlTag> ParseXml(string path)
{
var result = new List<XmlTag>();
using (var reader = XmlReader.Create(path))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
result.AddRange(ParseElement(
reader,
new XmlTag() { XML_TAG = reader.Name }));
}
else if (reader.NodeType == XmlNodeType.EndElement)
{
result.Add(new XmlTag()
{
XML_TAG = string.Format("/{0}",current.Name)
});
}
}
}
return result;
}
An example using XmlDocument. This will give slightly different result for self-enclosing tags (<description/> in your case). You can change this behaviour easily, depending on what you want.
private static IEnumerable<XmlTag> ProcessElement(XElement current)
{
if (current.HasElements)
{
yield return new XmlTag()
{
XML_TAG = current.Name.ToString(),
IsContainer = true
};
foreach (var tag in current
.Elements()
.SelectMany(e => ProcessElement(e)))
{
yield return tag;
}
yield return new XmlTag()
{
XML_TAG = string.Format("/{0}", current.Name.ToString()),
IsContainer = true
};
}
else
{
yield return new XmlTag()
{
XML_TAG = current.Name.ToString(),
XML_VALUE = current.Value
};
yield return new XmlTag()
{
XML_TAG = string.Format("/{0}",current.Name.ToString())
};
}
}
And using it:
var xdoc = XDocument.Load(#"test.xml");
var tags = ProcessElement(xdoc.Root).ToList();

Check if XML Element exists

How can someone validate that a specific element exists in an XML file? Say I have an ever changing XML file and I need to verify every element exists before reading/parsing it.
if(doc.SelectSingleNode("//mynode")==null)....
Should do it (where doc is your XmlDocument object, obviously)
Alternatively you could use an XSD and validate against that
You can iterate through each and every node and see if a node exists.
doc.Load(xmlPath);
XmlNodeList node = doc.SelectNodes("//Nodes/Node");
foreach (XmlNode chNode in node)
{
try{
if (chNode["innerNode"]==null)
return true; //node exists
//if ... check for any other nodes you need to
}catch(Exception e){return false; //some node doesn't exists.}
}
You iterate through every Node elements under Nodes (say this is root) and check to see if node named 'innerNode' (add others if you need) exists. try..catch is because I suspect this will throw popular 'object reference not set' error if the node does not exist.
//if the problem is "just" to verify that the element exist in the xml-file before you
//extract the value you could do like this
XmlNodeList YOURTEMPVARIABLE = doc.GetElementsByTagName("YOUR_ELEMENTNAME");
if (YOURTEMPVARIABLE.Count > 0 )
{
doctype = YOURTEMPVARIABLE[0].InnerXml;
}
else
{
doctype = "";
}
Not sure what you're wanting to do but using a DTD or schema might be all you need to validate the xml.
Otherwise, if you want to find an element you could use an xpath query to search for a particular element.
How about trying this:
using (XmlTextReader reader = new XmlTextReader(xmlPath))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
//do your code here
}
}
}
additionally to sangam code
if (chNode["innerNode"]["innermostNode"]==null)
return true; //node *parentNode*/innerNode/innermostNode exists
You can validate that and much more by using an XML schema language, like XSD.
If you mean conditionally, within code, then XPath is worth a look as well.
Following is a simple function to check if a particular node is present or not in the xml file.
public boolean envParamExists(String xmlFilePath, String paramName){
try{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(xmlFilePath));
doc.getDocumentElement().normalize();
if(doc.getElementsByTagName(paramName).getLength()>0)
return true;
else
return false;
}catch (Exception e) {
//error handling
}
return false;
}
A little bit late, but if it helps, this works for me...
XmlNodeList NodoEstudios = DocumentoXML.SelectNodes("//ALUMNOS/ALUMNO[#id=\"" + Id + "\"]/estudios");
string Proyecto = "";
foreach(XmlElement ElementoProyecto in NodoEstudios)
{
XmlNodeList EleProyecto = ElementoProyecto.GetElementsByTagName("proyecto");
Proyecto = (EleProyecto[0] == null)?"": EleProyecto[0].InnerText;
}
//Check xml element value if exists using XmlReader
using (XmlReader xmlReader = XmlReader.Create(new StringReader("XMLSTRING")))
{
if (xmlReader.ReadToFollowing("XMLNODE"))
{
string nodeValue = xmlReader.ReadElementString("XMLNODE");
}
}
Just came across the same problem and the null-coalescing operator with SelectSingleNode worked a treat, assigning null with string.Empty
foreach (XmlNode txElement in txElements)
{
var txStatus = txElement.SelectSingleNode(".//ns:TxSts", nsmgr).InnerText ?? string.Empty;
var endToEndId = txElement.SelectSingleNode(".//ns:OrgnlEndToEndId", nsmgr).InnerText ?? string.Empty;
var paymentAmount = txElement.SelectSingleNode(".//ns:InstdAmt", nsmgr).InnerText ?? string.Empty;
var paymentAmountCcy = txElement.SelectSingleNode(".//ns:InstdAmt", nsmgr).Attributes["Ccy"].Value ?? string.Empty;
var clientId = txElement.SelectSingleNode(".//ns:OrgnlEndToEndId", nsmgr).InnerText ?? string.Empty;
var bankSortCode = txElement.SelectSingleNode(".//ns:OrgnlEndToEndId", nsmgr).InnerText ?? string.Empty;
//TODO finish Object creation and Upsert DB
}
string name = "some node name";
var xDoc = XDocument.Load("yourFile");
var docRoot = xDoc.Element("your docs root name");
var aNode = docRoot.Elements().Where(x => x.Name == name).FirstOrDefault();
if (aNode == null)
{
return $"file has no {name}";
}
//I am finding childnode ERNO at 2nd but last place
If StrComp(xmlnode(i).ChildNodes.Item(xmlnode(i).ChildNodes.Count - 1).Name.ToString(), "ERNO", CompareMethod.Text) = 0 Then
xmlnode(i).ChildNodes.Item(xmlnode(i).ChildNodes.Count - 1).InnerText = c
Else
elem = xmldoc.CreateElement("ERNo")
elem.InnerText = c.ToString
root.ChildNodes(i).AppendChild(elem)
End If

Categories

Resources