Test for root node XML .NET - c#

I'm currently using the code below to attempt to check for a certain root node (rss) and a certain namespace\prefix (itunes), but it seems to be saying that the feed is valid even when supplied with a random web page URL instead of one pointing to a feed.
FeedState state = FeedState.Invalid;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(_url);
XmlNode root = xDoc.FirstChild;
if (root.Name.ToLower() == "rss" && root.GetNamespaceOfPrefix("itunes") == "http://www.itunes.com/dtds/podcast-1.0.dtd")
{
state = FeedState.Valid;
}
return state;
Can anybody tell me why this might be?

Found the solution now. Putting xDoc.Load(_url); in a try .. catch block and returning FeedState.Invalid upon exception seems to have solved my problems.
FeedState state = FeedState.Invalid;
XmlDocument xDoc = new XmlDocument();
try
{
xDoc.Load(_url);
}
catch
{
return state;
}
XmlNode root = xDoc.FirstChild;
if (root.Name.ToLower() == "rss" && root.GetNamespaceOfPrefix("itunes") == "http://www.itunes.com/dtds/podcast-1.0.dtd")
{
state = FeedState.Valid;
}
return state;

Related

How to add two actions depending on 'type' attribute of element in XML using webdriver in c#

I have elements stored in a config.xml file as part of my project, currently I have a method to 'setData' which will find the element by the id and then set its value to the user input (using a webdriver instance called FireFoxBrowser)
I want to add a type attribute to the xml to differentiate between 'inputs' which will use the current code and 'button' to add code that will click anything with this type. How can I use webdriver to write this code?
public void setData(string elementName, string elementValue)
{
XmlDocument docXml = null;
try
{
docXml = new XmlDocument();
string xmlPath = new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName + #"\config.xml";
docXml.Load(xmlPath);
XmlNode nd = docXml.SelectSingleNode(string.Format(#"//page[#url='{0}']", FireFoxBrowser.Url.ToString()));
if (nd != null)
{
var id = nd.SelectSingleNode(string.Format(#"element[#name='{0}']", elementName)).Attributes["id"].Value;
FireFoxBrowser.FindElement(By.Id(id)).Clear();
FireFoxBrowser.FindElement(By.Id(id)).SendKeys(elementValue);
}
}
finally
{
if (docXml != null)
docXml = null;
}
I was able to achieve this using the following line of code which differentiates between type attribute set:
var id = nd.SelectSingleNode(string.Format(#"element[#name='{0}']", elementName)).Attributes["id"].Value;

how to edit the nlog config file programmatically

i am trying to edit the logging level in the config file programmaticly.
foreach (var rule in LogManager.Configuration.LoggingRules)
{
if (m_loginglevelcomboBox.SelectedItem.ToString() == "Debug")
{
rule.EnableLoggingForLevel(LogLevel.Debug);
}
else
{
rule.EnableLoggingForLevel(LogLevel.Info);
}
}
//LogManager.ReconfigExistingLoggers();
I am not interested in calling the Reconfig,as the changes will affect the application on the fly.
I want the changes to be made when the application is restarted. so I need it to edit the config file.
i cant use xDocument ,as linq is not compatible with my .net version
so how can i edit the minlevel rule to debug/info ?
i used this to edit the logging level. I hope if this would help if some one stumbles across. If some one thinks it to be a bad idea, please let me know .
string configFilename = GetConfigFilePath();
XmlDocument doc = new XmlDocument();
doc.Load(configFilename);
XmlNode documentElement = doc.DocumentElement;
foreach (XmlNode node in documentElement.ChildNodes)
{
if (ruleDocumentNodeName.Equals(node.Name))
{
foreach (XmlNode childNode in node.ChildNodes)
{
if (loggerDocumentNodeName.Equals(childNode.Name))
{
XmlAttribute idAttribute = childNode.Attributes[minLevelAttributeName];
string currentValue = minLogingLevelComboBox.SelectedItem.ToString();
idAttribute.Value = currentValue;
doc.Save(configFilename);
MinLoggingLevelChanged = true;
}
}
}
}

Validating string value has the correct XML format

I am Having a sring for which i need to chek weather it has correct XML format like consistent start and end tags.
Sorry i tried to make string value well formated but could not :).
string parameter="<HostName>Arasanalu</HostName><AdminUserName>Administrator</AdminUserName><AdminPassword>A1234</AdminPassword><placeNumber>38</PlaceNumber>"
I tried with following check :
public bool IsValidXML(string value)
{
try
{
// Check we actually have a value
if (string.IsNullOrEmpty(value) == false)
{
// Try to load the value into a document
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(parameter);
// If we managed with no exception then this is valid XML!
return true;
}
else
{
// A blank value is not valid xml
return false;
}
}
catch (System.Xml.XmlException)
{
return false;
}
}
It was throwing error for correct as well as wrong format.
Please let me know how can i proceed.
Regards,
Channa
The content of the string you have do not actually form a valid xml document
Its missing a Root Element
string parameter="<HostName>Arasanalu</HostName><AdminUserName>Administrator</AdminUserName><AdminPassword>A1234</AdminPassword><PlaceNumber>38</PlaceNumber>";
XmlDocument doc = new XmlDocument(); \
doc.LoadXml("<root>" + parameter + "</root>"); // this adds a root element and makes it Valid
Root Element
There is exactly one element, called the root, or document element, no
part of which appears in the content of any other element.] For all
other elements, if the start-tag is in the content of another element,
the end-tag is in the content of the same element. More simply stated,
the elements, delimited by start- and end-tags, nest properly within
each other.
Always put proper tags in variable. Put <root> tag before and after you code. Try below code.
try
{
string unformattedXml = "<Root><HostName>Arasanalu</HostName><AdminUserName>Administrator</AdminUserName><AdminPassword>A1234</AdminPassword><PlaceNumber>38</PlaceNumber></Root>";
string formattedXml = XElement.Parse(unformattedXml).ToString();
return true;
}
catch (Exception e)
{
return false;
}

How to get innertext in an XML

I have the following XML file
<?xml version="1.0" encoding="utf-8"?>
<Comprobante version="2.2" serie="A" folio="35207" fecha="2013-05-31T11:51:48">
<Emisor rfc="" nombre="E">
<DomicilioFiscal calle="" noExterior="" colonia="" />
<ExpedidoEn calle="" noExterior="" colonia="" />
<RegimenFiscal Regimen="Regimen" />
</Emisor>
<Receptor rfc="" nombre="Z">
<Domicilio calle="" noExterior="" colonia="" />
</Receptor>
<Conceptos cantidad="1.000" unidad="COMISION" descripcion="PENDIENTE" valorUnitario="28.50000" importe="28.50" />
<Impuestos totalImpuestosTrasladados="3.14">
<Traslados>
<Traslado impuesto="IVA" tasa="11.00" importe="3.14" />
</Traslados>
</Impuestos>
<Addenda>
<ener:EstadoDeCuentaCombustible xmlns:ener="">
<ener:cadenaOriginal>||2.2|A|35207|2013-05-31T11:51:48|773463|2011|ingreso|Pago en una sola exhibicion|28.50|31.64|Tarjeta|Tijuana,Baja California|3213|ERE|E S.A. de C.V.|Prol|13351|Anexa e|Tijuana|Tijuana|Baja California|Mexico|22100|Prol|13351|Anexa e|Tijuana|Tijuana|Baja California|Mexico|22100|Regimen|XA|Z||||TIJUANA|TIJUANA|BAJA CALIFORNIA|Mexico||1.000|COMISION|PENDIENTE|28.50000|28.50|IVA|11.00|3.14|3.14||</ener:cadenaOriginal>
<ener:idRefund>98</ener:idRefund>
</ener:EstadoDeCuentaCombustible>
</Addenda>
</Comprobante>
I need to get the text that is inside (that long string)
Here's how I start the c# code
XmlDocument doc = new XmlDocument();
doc.Load("Route");
XmlNamespaceManager xnm = new XmlNamespaceManager(doc.NameTable);
xnm.AddNamespace("Documento", "http://www.sat.gob.mx/cfd/2");
xnm.AddNamespace("ener", "http://www.enercard.com.mx/cfd");
I've tried various ways...
//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda", xnm).FirstChild.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;
//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda//ener:EstadoDeCuentaCombustible", xnm).FirstChild.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;
//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda/Documento:cadenaOriginal", xnm).InnerXml;
this 3 ways always throw an exception...
I found another way that doesn't throw an exception, but it doesn't get the string
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("/Addenda/EstadoDeCuentaCombustible");
strOriginalString = "";
foreach (XmlNode node in nodes)
{
XmlNode child = node.SelectSingleNode("./cadenaOriginal");
if (child != null)
{
strOriginalString = child.InnerText;
break;
}
}
What am I doing wrong? or is there another way that I can get the string inside
This is somewhat simplified, and you'll need to deal with the namespace problems (one I note below), but otherwise, this is the basic construct:
XmlDocument doc = new XmlDocument();
try { doc.Load("c:\\temp\\test.xml"); }
catch (Exception ex) { }
XmlElement root = doc.DocumentElement;
String strOriginalString = "";
foreach (XmlNode node in root.SelectNodes("/Comprobante/Addenda"))
{
XmlNode child = node.SelectSingleNode("EstadoDeCuentaCombustible/cadenaOriginal");
if (child != null)
{
strOriginalString = child.InnerText;
break;
}
}
There's an issue with <ener:EstadoDeCuentaCombustible xmlns:ener=""> as the empty namespace is invalid.
You're missing xmlns:ener declaration on your XML document:
<ener:EstadoDeCuentaCombustible xmlns:ener="http://www.enercard.com.mx/cfd">
Fix that and you'll be able to use something like this:
string xpath = "/Comprobante/Addenda/ener:EstadoDeCuentaCombustible";
foreach (XmlNode estado in doc.SelectNodes(xpath, xnm))
{
Console.WriteLine("ener:cadenaOriginal={0}",
estado.SelectSingleNode("ener:cadenaOriginal", xnm).InnerText);
}
I find Linq2Xml easier to use. (Assuming you have a valid namespace in xmlns:ener="").
var xDoc = XDocument.Load(filename);
XNamespace ener = "your name space for ex ,http://www.enercard.com.mx/cfd";
var result = xDoc.Descendants(ener + "cadenaOriginal").First().Value;
Your second attempt looks the closest to what should work:
//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda//ener:EstadoDeCuentaCombustible", xnm).FirstChild.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;
But switch to this(edited):
//strOriginalString = doc.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;

using List.Add() method is breaking my code out of a foreach loops

So, essentially, I'm running into an interesting issue where, when the call to the "CreateXML()" function in the following code is made, an xelement is created as intended, but then, when I attempt to add it to a collection of xeleents, instead of continuing the foreach loop from which the call to "CreateXML()" originated, the foreach loop is broken out of, and a call is made to "WriteXML()". Additionally, though an XElement is created and populated, it is not added to the List. [for clarification, the foreach loops I am referring to live in the "ParseDoc()" method]
private List<XElement> _xelemlist;
private void WriteXml()
{
XElement head = new XElement("header", new XAttribute("headerattributename", "attribute"));
foreach (XElement xelem in _xelemlist)
{
head.Add(xelem);
}
XDocument doc = new XDocument();
doc.Add(head);
}
private void CreateXML(string attname, string att)
{
XElement xelem = new XElement("name", new XElement("child", new XAttribute(attname, att), segment));
_xelemlist.Add(xelem);
}
private void ExtractSegment(HtmlNode node)
{
HtmlAttribute[] segatts = node.Attributes.ToArray();
string attname = segatts[0].Value.ToString();
string att = node.InnerText.ToString();
CreateXML(attname, att);
}
private HtmlDocument ParseDoc(HtmlDocument document)
{
try
{
HtmlNode root = document.DocumentNode.FirstChild;
foreach (HtmlNode childnode1 in root.SelectNodes(".//child1"))
{
foreach (HtmlNode childnode2 in node.SelectNodes(".//child2"))
{
ExtractSegment(childnode2);
}
}
}
catch (Exception e) { }
WriteXml();
return document;
}
When I comment out the "List.Add()" in "CreateXML()" and step through the code, the foreach loop is not broken out of after the first iteration, and the code works properly.
I have no idea what I'm doing wrong (And yes, the code is instantiated by a public member, don't worry: I am only posting the relevant internal methods to my problem)... if anyone has come across this sort of behavior before, I would really appreciate a push in the right direction to attempt to correct it... Sepcifically: is the problem just poor coding, or is this behavior a result of a property of one of the methods/libraries I am using?
One Caveat: I know that I am using HTMLAgilityPack to parse a file and extract information, but a requirement on this code forces me to use XDocument to write said information... don't ask me why.
I have no idea what I'm doing wrong
This, for starters:
catch (Exception e) { }
That's stopping you from seeing what on earth's going on. I strongly suspect you've got a NullReferenceException due to _xelemlist being null, but that's a secondary problem. The main problem is that by pretending everything's fine whatever happens, with no logging whatsoever, the only way of getting anywhere is by debugging, and that's an awful experience when you don't need to go through it.
It's extremely rarely a good idea catch exceptions and swallow them without any logging at all. It's almost never a good idea to do that with Exception.
Whenever you have a problem which is difficult to diagnose, improve your diagnostic capabilities first. That way, when you next run into a problem, it'll be easier to diagnose.
Declare the List this way,
private List<XElement> _xelemlist = new List<XElement>();
In your foreach loop, you are attempting to use XElement head as a list of XElements when you add() to it. This should probably be a list of XElements?
Might I suggest switching to using XmlDocument?
Here is some sample code which I have written for work (changed to protect my work :D), and we are using it rather well.
Code:
XmlDocument doc = new XmlDocument();
XmlNode root;
if(File.Exists(path + "\\MyXmlFile.xml"))
{
doc.Load(path + "\\MyXmlFile.xml");
root = doc.SelectSingleNode("//Library");
}
else
{
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(dec);
root = doc.CreateElement("Library");
doc.AppendChild(root);
}
XmlElement book = doc.CreateElement("Book");
XmlElement title = doc.CreateElement("Title");
XmlElement author = doc.CreateElement("Author");
XmlElement isbn = doc.CreateElement("ISBN");
title.InnerText = "Title of a Book";
author.InnerText = "Some Author";
isbn.InnerText = "RandomNumbers";
book.AppendChild(title);
book.AppendChild(author);
book.AppendChild(isbn);
root.AppendChild(book);
doc.Save(path + "\\MyXmlFile.xml");

Categories

Resources