I am parsing the XML in C# this XML:
<Resident Type="R">
<Payment>1218</Payment>
</Resident>
I am parsing this way(please answer this same way, not other methods)
XmlDocument parsed_xml = new XmlDocument();
parsed_xml.LoadXml(dto.xml);
XmlNodeList test = parsed_xml.SelectNodes("/IER/Credit/Loan/LoanApp/Applicant/Personal/Individuals/Individual/Resident/Peyment");
if (xnList != null)
PAYMENT = xnList.Item(0).InnerText;
with this code I can get the Payment value that is 1218 but how I can get the attribute value of Type that is "R" ?
You'll want to look at the ParentNode to get the attribute.
string residentType = xnList[0].ParentNode.Attributes["Type"].Value;
Related
I have a xml like this:
<xmlRootNode>
<levelOneChildNode>
Some text
<levelTwoChildNode>
<levelThreeChildNode>More text</levelThreeChildNode>
</levelTwoChildNode>
</levelOneChildNode>
</xmlRootNode>
I can't change the xml format because my client wants this format. How I should create and decorate "levelOneChildNode" class for a correct serialization? I can't use XmlElement or XmlAttribute. The only way to do this than I've thought is put "Some text" as a XmlElement and make a
string.replace("<textNode>", string.empty).replace("</textNode>", string.empty)
with de serialized xml to remove de tag but this is a crapy solution.
Any ideas without manual xml manipulation?
I guess you have two options, both of them related to manual xml-manipulation:
Use
XmlWriter
to write elements one by one.
Fill general-purpose
XmlDocument,
and save it.
Set/Retrieve/Append/Create XmlNotes (values):
//file name
string filename = #"d:\temp\XMLFile2.xml";
//create new instance of XmlDocument
XmlDocument _doc = new XmlDocument();
//load from file
_doc.Load(filename);
// Change text in xml
XmlNode node= _doc.SelectSingleNode("xmlRootNode/levelOneChildNode"); // [index of user node]
node.InnerText = value;
_doc.Save(#"path");
// Retrive value from xml
XmlNode node = _doc.SelectSingleNode("xmlRootNode/levelOneChildNode/levelTwoChildNode/someAttribute");
string value = node.InnerText;
// read or write to more elements
foreach (XmlNode node in doc.SelectNodes("xmlRootNode/levelOneChildNode/levelTwoChildNode"))
{
string data= node.SelectSingleNode("someAttribute").InnerTex; // get value of someAttribute.
node.InnerText = value;
}
// Append Note to levelOneChildNode Note
// Create second node
XmlNode secondNode = doc.CreateElement("SecondLevelNode");
secondNode .InnerText = "This title is created by code"
XmlNode firstNode= _doc.SelectSingleNode("xmlRootNode/levelOneChildNode");
firstNode.AppendChild(secondNode );
_doc.Save(#"path");
I am trying to get XML values from the following XML node:
<StockQuotes>
<Stock>
<Symbol>LLOY.L</Symbol>
<Last>76.27</Last>
<Date>8/29/2014</Date>
</Stock>
</StockQuotes>
Here is my code:
XmlDocument quoteXML = new XmlDocument();
string strData = myXMLfile;
quoteXML.LoadXml(strData);
XmlNode nodes = quoteXML.SelectSingleNode("StockQuotes/Stock/Last/Date");
string strPrice = nodes["Last"].InnerText;
string strDate = nodes["Date"].InnerText;
Response.Write( strPrice + strDate );
I am getting the error:
Object reference not set to an instance of an object.
when I write the whole string strData to the view I get all of the XML so I know the file is valid.
SOURCE OF THE PROBLEM:
quoteXML.SelectSingleNode("StockQuotes/Stock/Last/Date"); SelectSingleNode call will return representation of <Date>8/29/2014</Date>,
But you try to access subnodes ["Last"] and ["Date"], that are not child nodes of <Date>8/29/2014</Date> and taking into account that indexer returns:
The first XmlElement that matches the specified name. It returns a
null reference (Nothing in Visual Basic) if there is no match.
nodes["Last"] and nodes["Base"] will be both null, resulting in NullReferenceException on .InnerText property access.
SOLUTION:
Use
XmlNode nodes = quoteXML.SelectSingleNode("StockQuotes/Stock");
to access Stock node instead.
The issue was with special charchters in the XML feed. I have resolved the issue and used:
'string strData = WebService.GetDate(); // returns xml as string
string decoded = WebUtility.HtmlDecode(strData); quoteXML.LoadXml(decoded);
XmlDocument xml = new XmlDocument();
xml.LoadXml(decoded);
XmlNodeList xnList = xml.SelectNodes("/StockQuotes/Stock");
foreach (XmlNode xn in xnList)
{
strQuote = xn["Last"].InnerText;
}'
I am trying to write a test function in C# that read data from an XML file and parse into Selenium testing methods , the XML code is like:
<home>
<ask_frame>
<button>
<id>Object ID<id>
<xpath>Object XPath<xpath>
<textbox>
<id>Object ID<id>
<xpath>Object XPath<xpath>
</ask_frame>
<search_frame>
<id>Object ID<id>
<xpath>Object XPath<xpath>
</search_frame>
<home>
I am trying to create a loop that read the id and xpath value from these nodes and parse them into an method for searching a webpage element by id and xpath. My initial attempt was:
Code updated
public void CheckIdTest()
{
driver.Navigate().GoToUrl(baseURL + "FlightSearch");
XmlDocument xd = new XmlDocument();
xd.Load(#"C:\XMLFile1.xml");
XmlNodeList mainlist = xd.SelectNodes("//home/*");
XmlNode mainroot = mainlist[0];
foreach (XmlNode xnode in mainroot)
{
string objID = xnode.SelectSingleNode("id").InnerText;
string objXPath = xnode.SelectSingleNode("XPath").InnerText;
objID = objID.Trim();
objXPath = objXPath.Trim();
String checkValue = "ObjID value is: " + objID + Environment.NewLine+ "ObjXPath value is: " + objXPath;
System.IO.File.WriteAllText(#"C:\checkvalue.txt", checkValue);
objectCheck(objXPath, objID);
}
}
I have put a String and checked that correct values for ObjID and ObjXPath have been achieved, but this loop also went only twice (checked 2 nodes in first branch). How could I make it runs through every node in my XML?
Any suggestions and explanations to the code will be highly appreciated.
Basically these two lines are using incorrect XPath :
XmlNodeList idlist = xd.SelectNodes("id");
XmlNodeList xpathlist = xd.SelectNodes("XPath");
<id> and <xpath> nodes aren't located directly at the root level, so you can't access it just like above. Besides, xpath is case-sensitive so you should've used "xpath" instead of "XPath". Try to fix it like this :
XmlNodeList idlist = xd.SelectNodes("//id");
XmlNodeList xpathlist = xd.SelectNodes("//xpath");
or more verbose :
XmlNodeList idlist = xd.SelectNodes("home/*/id");
XmlNodeList xpathlist = xd.SelectNodes("home/*/xpath");
UPDATE :
Responding to your comment about looping problem, I think you want to change it like this :
foreach (XmlNode xnode in mainroot.ChildNodes)
{
string objID = xnode.SelectSingleNode("id").InnerText;
string objXPath = pathroot.SelectSingleNode("xpath").InnerText;
objectCheck(objID, objXPath);
}
You are getting this error because you are trying to use an object that is null i.e not instantiated.
Put in a breakpoint at the line
XmlDocument xd = new XmlDocument();
and step through line by line till you find where the nothing.null reference is.
It should not take long to find out what the problem is.
I am trying to make an XML parser for XML documents, where there are some optional attributes in nodes and I am looking for an elegant way, how to solve the problem with "Object reference not set to an instance".
I have read this topic, which is very similar and the following code seemed very promising:
string text = (string) foo.Element("Text") ?? "Default value";
However, when I tried to implement it, the "Object reference not set to an instance" still occurred and so I am looking for another solution. Here is a piece of my desperate effort.
XML file 1:
...
<Message id ="1" appendix = "abc" ></Message>
...
XML file 2:
...
<Message id ="2" ></Message>
...
My parser (called in a cycle for each file in the folder):
public MyNode Parse(string file)
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load(file);
MyNode node = new MyNode();
node.messageID = (string)xDoc.GetElementsByTagName("Message")[0].Attributes["id"].Value ?? "NULL";
node.appendix = (string)xDoc.GetElementsByTagName("Message")[0].Attributes["appendix"].Value ?? "NULL";
return node;
}
Could you help me out?
Following LINQ to XML query will return MyNode object filled with values of message id and appendix attributes. If some attribute not found, then defalult value "NULL" is used:
var xDoc = XDocument.Load(file);
var node = xDoc.Descendants("Message")
.Select(m => new MyNode {
messageID = (string)m.Attribute("id") ?? "NULL",
appendix = (string)m.Attribute("appendix") ?? "NULL"
}).FirstOrDefault();
If there is no Message elements in your xml document, then null will be returned.
BTW when you are using LINQ to XML its better to use casting node to (string) than accessing its Value property. Because if node not found in document, then you'll get NullReferenceException if you will try to get Value property of null. But when you cast node to string, you simply get null value instead of exception. That allows you to provide default value with null-coalescing operator.
Unfortunately this only works if the Value is null, not if the actual XAttribute is null.
You'll have to do something like this:
XAttribute temp = xDoc.GetElementsByTagName("Message")[0].Attributes["appendix"];
if (temp == null)
{
node.appendix = temp.Value;
}
else
{
node.appendix = "NULL";
}
I'm using C#.
I have an XmlElement with InnerXml
<b xpage="5" xid="85">3-6. Title</b><i>. The Content</i>
which makes the InnerText as
3-6. Title. The Content
Now I have a match variable with value
3-6. Title.
What i wanted to get is the rest of the portion of InnerXml ..ie.
<i> The Content</i>
Please Help.
It looks like you have two sibling nodes, B and I. To match a specific instance of B, use an XPath text selector.
string xpath = "//*/b[text()='3-6. Title']"; // replace wildcard with real path
http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/db2/rbafzxpathqueryexmp.htm
Once you have matched B, you can use the NextSibling property to find I
http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.nextsibling.aspx
in the OuterXml property you get the xml string you want <i>. The Content</i>
XmlDocument doc = new XmlDocument();
doc.LoadXml("<rootxml><b xpage=\"5\" xid=\"85\">3-6. Title</b><i>. The Content</i></rootxml>");
XmlNode root = doc.FirstChild;
var completeString = root["b"].OuterXml + root["i"].OuterXml;
if (completeString.StartsWith("3-6. Title.") {
XmlElement xmlElement = root["i"];
var iContent = xmlElement.OuterXml;
Console.WriteLine(iContent);
}
hope this helps