Get single value from XML File in C# - c#

I am trying to pull a single value from XML stored in a variable in a C# console application.
Here is my XML:
string myxml = #"<?xml version='1.0' encoding='utf-8'?>
<params>
<rowsEffected>1</rowsEffected>
</params>
<data>
<rowData>
<row>
<answer>1234</answer>
</row>
</rowData>
</data>";
var doc = XDocument.Parse(myxml); //This is as far as I can get
I have read thru many tutorials but can't get this simple task.
I want to extract the value from the "answer" tag, so my result should be 1234
The XML will always have one record.
Any help would be greatly appreciated.

Your XML is invalid. There can only be one root element. In your XML params and data are both top level elements which is not allowed. Try it out for yourself at: http://www.xmlvalidation.com/

Related

How to parse a XML with nested XML text

Trying to read XML file with nested XML object with own XML declaration. As expected got exception:
Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.
How can i read that specific element as text and parse it as separate XML document for later deserialization?
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Items>
<Item>
<Target type="System.String">Some target</Target>
<Content type="System.String"><?xml version="1.0" encoding="utf-8"?><Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>
Every approach i'm trying fail due to declaration exception.
var xml = System.IO.File.ReadAllText("Info.xml");
var xDoc = XDocument.Parse(xml); // Exception
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml); // Exception
var xmlReader = XmlReader.Create(new StringReader(xml));
xmlReader.ReadToFollowing("Content"); // Exception
I have no control over XML creation.
The only way I would know is by getting rid of the illegal second <?xml> declaration. I wrote a sample that will simply look for and discard the second <?xml>. After that the string has become valid XML and can be parsed. You may need to tweak it a bit to make it work for your exact scenario.
Code:
using System;
using System.Xml;
public class Program
{
public static void Main()
{
var badXML = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<Data>
<Items>
<Item>
<Target type=""System.String"">Some target</Target>
<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?><Data><Items><Item><surname type=""System.String"">Some Surname</surname><name type=""System.String"">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>";
var goodXML = badXML.Replace(#"<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?>"
, #"<Content type=""System.String"">");
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(goodXML);
XmlNodeList itemRefList = xmlDoc.GetElementsByTagName("Content");
foreach (XmlNode xn in itemRefList)
{
Console.WriteLine(xn.InnerXml);
}
}
}
Output:
<Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data>
Working DotNetFiddle: https://dotnetfiddle.net/ShmZCy
Perhaps needless to say: all of this would not have been needed if the thing that created this invalid XML would have applied the common rule to wrap the nested XML in a <![CDATA[ .... ]]> block.
The <?xml ...?> processing declaration is only valid on the first line of an XML document, and so the XML that you've been given isn't well-formed XML. This will make it quite difficult to parse as is without either changing the source document (and you've indicated that's not possible) or preprocessing the source.
You could try:
Stripping out the <?xml ?> instruction with regex or string manipulation, but the cure there may be worse than the disease.
The HTMLAgilityPack, which implements a more forgiving parser, may work with an XML document
Other than that, the producer of the document should look to produce well-formed XML:
CDATA sections can help this, but be aware that CDATA can't contain the ]]> end tag.
XML escaping the XML text can work fine; that is, use the standard routines to turn < into < and so forth.
XML namespaces can also help here, but they can be daunting in the beginning.

Malformed xml not parsing in XDocument.Parse

Please help, I have an xml document that I want to parse with XDocument. But the xml string that I have has multiple xmlns attributes that is empty. xmlns="" and the moment I remove it it parse, But I receive this from a webservice. I tried replacing it but every which way I try it only replaces one " and I am left with an invalid xmlstring <test xmlns="> I tried regex, I tried the Replace function I tried every know way, and I am now stuck,
Any Suggestions?
string xmlString = #"
<UserFile xmlns=""http://temuri.org"">
<user>
<UserName>Daniel</UserName>
<UserSurname>Vrey</UserSurname>
<Toys xmlns="">
<TToy>Toyota</TToy>
<TToy>Ford</TToy>
</Toys>
</user>
</UserFile>";
XDocument d = XDocument.Parse(xmlString);

How to load an XML Document to display as specific input format

I am currently trying to load an XML document to a C# program so that I can send it as a soap request.
Here is the XML Document I am trying to reference. It has a potential infinite number of rows.
<?xml version="1.0" encoding="UTF-8" ?>
<ROWSET>
<ROW num="1">
<USER_ID></USER_ID>
<FIRST_NAME>John</FIRST_NAME>
<MIDDLE_NAME></MIDDLE_NAME>
<LAST_NAME>Doe</LAST_NAME>
<EMPLOYEE_NO>12345</EMPLOYEE_NO>
<HOME_PHONE></HOME_PHONE>
<EMPLOYEE_STATUS_>A</EMPLOYEE_STATUS_>
<HIRE_DATE>05/17/2010</HIRE_DATE>
<DEPARTMENT>Engineering</DEPARTMENT>
<POSITION>Controls Engineer</POSITION>
<SHIFT>N</SHIFT>
<REPORTS_TO>Everhart,Robert</REPORTS_TO>
<PAY_TYPE>H</PAY_TYPE>
<EMPLOYEE_TYPE>R</EMPLOYEE_TYPE>
<TERMINATION_DATE></TERMINATION_DATE>
<PCN_CODE>Company_RV</PCN_CODE>
</ROW>
<ROW num="2">
<USER_ID>RV12345</USER_ID>
<FIRST_NAME>Jane</FIRST_NAME>
<MIDDLE_NAME>G</MIDDLE_NAME>
<LAST_NAME>Doe</LAST_NAME>
<EMPLOYEE_NO>123455</EMPLOYEE_NO>
<HOME_PHONE></HOME_PHONE>
<EMPLOYEE_STATUS_>A</EMPLOYEE_STATUS_>
<HIRE_DATE>09/15/2008</HIRE_DATE>
<DEPARTMENT>Shipping</DEPARTMENT>
<POSITION>Shipping Coordinator</POSITION>
<SHIFT>2</SHIFT>
<REPORTS_TO>Hajkova,Karin</REPORTS_TO>
<PAY_TYPE>H</PAY_TYPE>
<EMPLOYEE_TYPE>R</EMPLOYEE_TYPE>
<TERMINATION_DATE></TERMINATION_DATE>
<PCN_CODE>Company_RV</PCN_CODE>
I need to format this file into:
<ResultSet>
<RowCount>1</RowCount>
<Rows>
<Row>
<Columns>
<Column>
<Value>jdoe</Value>
<Name>User_ID</Name>
</Column>
<Column>
<Value>John</Value>
<Name>FIRST_NAME</Name>
and so forth
Once the xml file has been loaded and massaged into the correct format the variable containing the xml data would be placed into a soap envelope.
Try using the xsd tool with the original XML in order to create classes to serialize the XML on memory.
Then use the XmlSerializer in order to get all into memmory:
XmlSerializer serializer = new XmlSerializer(XmlClassTypeYouCreatedOnXsdTool);
XmlReader reader = new XmlTextReader(xml);
var instance = serializer.Deserialize(reader);
Use the same xsd tool with the output xml form you want to create in order to form another serializable classes.
Create functions to transform one object to another then send the object to your SOAP webreferences or use the same XmlSerializer and call Serialize to generate XML to your SOAP messages.

how Deserializing this type of xml file?

<row>
<id>1</id>
<code></code>
<name></name>
<address></address>
<state></state>
<zone>?</zone>
</row>
<row>
<id>2</id>
<code>AA</code>
<name>Ataria</name>
<address>Sitapur National Highway 24, Uttar Pradesh</address>
<state>Uttar Pradesh</state>
<zone>NER</zone>
</row>
i have no root element in this xml file only row element start and end this xml file.
how Deserializing this type of data ? in c#
If you sure that missing root is only the one issue with your XML - just add it manually:
string fileContent = File.ReadAllText(path);
string rawXml = "<root>" + fileContent + "</root>";
// now you can use LINQ-to-XML or whatever
XDocument xdoc = XDocument.Load(rawXml);
You can also load an XML Fragment directly, via
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create("tracelog.xml", settings))
{
while (reader.Read())
{
// Process each node of the fragment,
// possibly using reader.ReadSubtree()
}
}
You would create XElements by passing the results of reader.ReadSubTree() to XElement.Load(...).
Well to start with, it's not an XML file - or at least, it doesn't represent an XML document.
One option would be to copy the file into a new file which does have document start/end tags... then you can load it as a normal document. Just create a file, write a document start tag, copy the contents of this file, then write a document end tag, and close the file handle. You could even do this in memory.
Alternatively, it may be possible to read it as it is, in fragments - possibly via XmlReader. I can't say it's something I've done, and I'd generally encourage you to create a full XML file instead, as then you'll be on more familiar territory.
its not an XML file if it doesn't have the root. parser will throw an error if you try to parse it. you can do this way
<?xml version="1.0"?>
<Root>
--- add your file content here
</Root>
then give this file path to the parser.

How to access XML String values in C#?

I'm learning to use ReST Web services and I need to find out how to get a specific value from the xml string that is returned. How can I simply get 1 value from an xml String? All I want is one value. Is there some way to convert this string into something with an indexer?
I'm using Yahoo Geocoding service. Results:
<ResultSet version="1.0">
<Error>0</Error>
<ErrorMessage>No error</ErrorMessage>
<Locale>us_US</Locale>
<Quality>87</Quality>
<Found>1</Found>
−
<Result>
<quality>85</quality>
<latitude>86.457310</latitude>
<longitude>-73.262245</longitude>
<offsetlat>46.457311</offsetlat>
<offsetlon>-73.262071</offsetlon>
<radius>500</radius>
<name/>
<line1>1234 N Main St</line1>
<line2>Anytown, New York 12345</line2>
<line3/>
<line4>United States</line4>
<house>1234</house>
<street>N Main St</street>
<xstreet/>
<unittype/>
<unit/>
<postal>12345</postal>
<neighborhood/>
<city>New York</city>
<county>Albany County</county>
<state>New York</state>
<country>United States</country>
<countrycode>US</countrycode>
<statecode>NY</statecode>
<countycode/>
<uzip>12345</uzip>
<hash>E692D20CBDF86A2E</hash>
<woeid>12783988</woeid>
<woetype>11</woetype>
</Result>
</ResultSet>
You could use Linq to XML
XDocument xmlfile= XDocument.Load("PATH TO XML DOC");
var test = from xml in xmlfile.Descendants("item_name")
select new { Title = (string)xml.Element("title").Value };
That's one way.
Use XPath to address the node you are interested in:
http://msdn.microsoft.com/en-us/library/d271ytdx(v=VS.90).aspx
To transform XML string into an XML document
XmlDocument doc = new XmlDocument();
doc.LoadXml(yourString);
Here is a good introduction to XPath: http://www.codeproject.com/KB/cpp/myXPath.aspx
See my question on Easiest way to read XML with attributes. I found that using xsd.exe to generate a xsd which allows you managed access to the XML was the simplest way to access the XML data. LINQ2XML was also pretty easy to use.

Categories