How to generate an XML file - asp.net

I need to create an xml file here
bool result= false;
How to achieve this in ASP.NET with C# syntax. result is value that I need to add in the XML file.
I need to create an XML file under a folder with contents like this
<?xml version="1.0" encoding="utf-8" ?>
<user>
<Authenticated>yes</Authenticated>
</user>
thank you

XElement xml = new XElement("user",
new XElement("Authenticated","Yes"))
);
xml.Save(savePath);
It works for .net 3 and above, but
You can use XmlDocument for later versions
XmlDocument xmlDoc = new XmlDocument();
// Write down the XML declaration
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0","utf-8",null);
// Create the root element
XmlElement rootNode = xmlDoc.CreateElement("user");
xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
xmlDoc.AppendChild(rootNode);
// Create the required nodes
XmlElement mainNode = xmlDoc.CreateElement("Authenticated");
XmlText yesText= xmlDoc.CreateTextNode("Yes");
mainNode.AppendChild(yesText);
rootNode.AppendChild(mainNode);
xmlDoc.Save(savePath);
You can use XmlWriter too as suggests #marc_s or at least you can store xml to the file like sting
using(StreamWriter sw = new StreamWriter(savePath))
{
sw.Write(string.Format("<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<user><Authenticated>{0}</Authenticated></user>","Yes"));
}

How about this:
XmlTextWriter xtw = new XmlTextWriter(#"yourfilename.xml", Encoding.UTF8);
xtw.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");
xtw.WriteStartElement("user");
xtw.WriteStartElement("Authenticated");
xtw.WriteValue(result);
xtw.WriteEndElement(); // Authenticated
xtw.WriteEndElement(); // user
xtw.Flush();
xtw.Close();
Or if you prefer to build up your XML file in memory, you can also use the XmlDocument class and its methods:
// Create XmlDocument and add processing instruction
XmlDocument xdoc = new XmlDocument();
xdoc.AppendChild(xdoc.CreateProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\""));
// generate <user> element
XmlElement userElement = xdoc.CreateElement("user");
// create <Authenticated> subelement and set it's InnerText to the result value
XmlElement authElement = xdoc.CreateElement("Authenticated");
authElement.InnerText = result.ToString();
// add the <Authenticated> node as a child to the <user> node
userElement.AppendChild(authElement);
// add the <user> node to the XmlDocument
xdoc.AppendChild(userElement);
// save to file
xdoc.Save(#"C:\yourtargetfile.xml");
Should work on any version of the .NET framework, if you have a using System.Xml; clause at the top of your file.
Marc

If you want to generate the XML and then give the user a choice to save the XML in their workstation, check the post below. It explains that process in detail.
Generating XML in Memory Stream and download

Related

SelectSingleNode function returns nothing from XML document [duplicate]

How to parse the xml file?
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>link</loc>
<lastmod>2011-08-17T08:23:17+00:00</lastmod>
</sitemap>
<sitemap>
<loc>link</loc>
<lastmod>2011-08-18T08:23:17+00:00</lastmod>
</sitemap>
</sitemapindex>
I am new to XML, I tried this, but it seems to be not working :
XmlDocument xml = new XmlDocument(); //* create an xml document object.
xml.Load("sitemap.xml");
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap");
foreach (XmlNode xn in xnList)
{
String loc= xn["loc"].InnerText;
String lastmod= xn["lastmod"].InnerText;
}
The problem is that the sitemapindex element defines a default namespace. You need to specify the namespace when you select the nodes, otherwise it will not find them. For instance:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
Normally speaking, when using the XmlNameSpaceManager, you could leave the prefix as an empty string to specify that you want that namespace to be the default namespace. So you would think you'd be able to do something like this:
// WON'T WORK
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath
However, if you try that code, you'll find that it won't find any matching nodes. The reason for this is that in XPath 1.0 (which is what XmlDocument implements), when no namespace is provided, it always uses the null namespace, not the default namespace. So, it doesn't matter if you specify a default namespace in the XmlNamespaceManager, it's not going to be used by XPath, anyway. To quote the relevant paragraph from the Official XPath Specification:
A QName in the node test is expanded into an expanded-name using the
namespace declarations from the expression context. This is the same
way expansion is done for element type names in start and end-tags
except that the default namespace declared with xmlns is not used: if
the QName does not have a prefix, then the namespace URI is null (this
is the same way attribute names are expanded). It is an error if the
QName has a prefix for which there is no namespace declaration in the
expression context.
Therefore, when the elements you are reading belong to a namespace, you can't avoid putting the namespace prefix in your XPath statements. However, if you don't want to bother putting the namespace URI in your code, you can just use the XmlDocument object to return the URI of the root element, which in this case, is what you want. For instance:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
Sitemap has 2 sub nodes "loc" and "lastmod". The nodes that you are accessing are "name" and "url". that is why you are not getting any result. Also in your XML file the last sitemap tag is not closed properly with a corresponding Kindly try xn["loc"].InnerText and see if you get the desired result.
I would definitely use LINQ to XML instead of the older XmlDocument based XML API. You can accomplish what you are looking to do using the following code. Notice, I changed the name of the element that I am trying to get the value of to 'loc' and 'lastmod', because this is what is in your sample XML ('name' and 'url' did not exist):
XElement element = XElement.Parse(XMLFILE);
IEnumerable<XElement> list = element.Elements("sitemap");
foreach (XElement e in list)
{
String LOC= e.Element("loc").Value;
String LASTMOD = e.Element("lastmod").Value;
}

Error while creating XML file

I am trying to create a simple XML file, but I am getting the exception
Object reference not set to an instance of an object
at this part:
doc.Root.Add(persons);
What am I doing wrong?
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", null));
XElement persons = new XElement("Persons");
XElement[] el ={new XElement("PersonInfo",new XAttribute("ID",1),
new XElement("Name","ali"),
new XElement("Phone","222222"))
};
persons.Add(el);
doc.Add(persons);
doc.Save("PhoneBook.xml", SaveOptions.None);
Response.Write("ok");
}
You should just use:
doc.Add(persons);
Then you will get this XML:
<Persons>
<PersonInfo ID="1">
<Name>ali</Name>
<Phone>222222</Phone>
</PersonInfo>
</Persons>
An empty XDocument has no Root. That's why you get a NullReferenceException when you try to access it.

XmlDocument difficulties returning specific nodes/elements

first post. I hope it meets with the rules of asking questions.
I'm in a bit of bother with an xml document (its an API returned Xml). Now it uses a multitude of internet (http based) security measures which I have worked thru and I am now able to return the the top tier of nodes that are not nested.
however there are a few nodes which are nested under these and I need to return some of these values.
I'm set on using XMLDocument to do this, and I'm not interested in using XPath.
I should also note that I'm using the .Net 4.5 environment.
Example XML
<?xml version="1.0" encoding="utf-8"?>
<results>
<Info xmlns="http://xmlns.namespace">
<title>This Title</title>
<ref>
<SetId>317</SetId>
</ref>
<source>
<name>file.xxx</name>
<type>thisType</type>
<hash>cc7b99599c1bebfc4b8f12e47aba3f76</hash>
<pers>65.97602</pers>
<time>02:20:02.8527777</time>
</source>
....... Continuation which is same as above
Ok so above is the Xml that gets returned from the API, now, I can return title node no problem. What I would also like to return is any of the node values in the Element, for example the pers node value. But I only want to return one (as there are many in the existing xml further down)
Please note that there is an xmlns in the Info node which may not be allowing me to return the values.
So here is my code
using (var response = (HttpWebResponse) request.GetResponse())
{
//Get the response stream
using (Stream stream = response.GetResponseStream())
{
if (stream != null)
{
var xDoc = new XmlDocument();
var nsm = new XmlNamespaceManager(xDoc.NameTable);
nsm.AddNamespace("ns", XmlNamespace);
//Read the response stream
using (XmlReader xmlReader = XmlReader.Create(stream))
{
// This is straight forward, we just need to read the XML document and return the bits we need.
xDoc.Load(xmlReader);
XmlElement root = xDoc.DocumentElement;
var cNodes = root.SelectNodes("/results/ns:Info", nsm);
//Create a new instance of Info so that we can store any data found in the Info Properties.
var info = new Info();
// Now we have a collection of Info objects
foreach (XmlNode node in cNodes)
{
// Do some parsing or other relevant filtering here
var title = node["title"];
if (title != null)
{
info.Title = title.InnerText;
_logger.Info("This is the title returned ############# {0}", info.Title);
}
//This is the bit that is killing me as i can't return the any values in the of the sub nodes
XmlNodeList sourceNodes = node.SelectNodes("source");
foreach (XmlNode sn in sourceNodes)
{
XmlNode source = sn.SelectSingleNode("source");
{
var pers = root["pers"];
if (pers != null) info.pers = pers.InnerText;
_logger.Info("############FPS = {0}", info.pers);
}
}
}
}
Thanks in advance for any help
So I finally figured it out.
Here is the code that gets the subnodes. Basically I wasn't using my namespace identifier or my namespace for returning subnodes within the "Source" node.
For anybody else in this situation,
When you declare your name space there are to parts to it, a namespace identifier which is anything you want it to be in my case I chose "ns" and then the actual namespace in the XML file which is prefixed by xmlns and will contain something like for example: "http://xmlns.mynamespace".
So when searching subnodes inside the top level you need to declare these namespaces for the main node of the subnode you want to get.
// get the <source> subnode using the namespace to returns all <source> values
var source = node.SelectSingleNode("ns:source", nsm);
if (source != null)
{
info.SourceType = source["type"].InnerText;
info.Pers = source["pers"].InnerText;
_logger.Info("This SourceNode is {0}", info.SourceType);
_logger.Info("This PersNode is {0}", info.FramesPerSecond);
}
I hope this helps somebody else that's chasing their tails as I have.
Thanks

Extracting userid from Inbound headers

I have to read element from Inbound Header...
I am assigning inbound header using WCF.InboundHeaders to a string....
now my problem is my inbounde header is looking like this
InboundHeaders
<headers><s:userid xmlns:s="http://www.w3.org/2003/05/soap-envelope">testuser</s:userid>
<s:applicationid xmlns:s="http://www.w3.org/2003/05/soap-envelope">assistworkerweb</s:applicationid>
<a:Action s:mustUnderstand="1" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">http://Request</a:Action><a:To s:mustUnderstand="1" xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
Now i need to extract user id from it ..how to extract user id from it..
You haven't mentioned where or how your string is stored (that is populated with your WCF.InboundHeaders), however I would use a simple fragment of XPath to extract the UserId. If you were extracting this using a C# helper, you could do something along the lines of (note, this is untested, however its pretty much there):
XmlDocument doc = new XmlDocument();
doc.Load([WCF.InboundHeaders Xml Fragment]);
// Create an XmlNamespaceManager to add 'soap-envelope' namespace
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("s", "http://www.w3.org/2003/05/soap-envelope");
// Select the UserId
XmlNode userId = doc.SelectSingleNode("/headers/s:userid", nsmgr);
Console.WriteLine(userId.InnerXml);
You may also want to serialize the Xml fragment into a .Net object and retrieve the UserId in that manner.

How to ignore comments when parsing xml in asp.net

Seems like this should be easy, but I'm not finding a simple configuration setting. Basically I have a page that will be parsing xml files that may have some comment tags in them. I'm loading it as an xml doc and looping through a particular node of the document and I'm running into problems because it's counting the comment as a child node. Any way to tell asp.net not to look at comments other than writing my own check for <!-- ?
If you use XmlNode, then that has a NodeType property. Ignore the nodes where that has a value of "Comment".
An XNode has the same property.
Use XmlReaderSettings.IgnoreComments:
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.IgnoreComments = true;
using (XmlReader reader = XmlReader.Create("input.xml", readerSettings))
{
XmlDocument myData = new XmlDocument();
myData.Load(reader);
// etc...
}

Resources