Read XML values Webservice - c#

I want to read xml on runtime, without save it on a path
After my searching i find that, In console application i need to use Console.Out for displaying result
xmlSerializer.Serialize(Console.Out, patient);
In Windows / Web Application we need to set path like
StreamWriter streamWriter = new StreamWriter(#"C:\test.xml");
but i need to read xml with out save it, i am using Webserive where i need to read it and take a decision that either it is valid or not
I hope i define it clearly..

Use the XmlDocument object.
There are several ways to load the XML, you can use the XmlDocument.Load() and specify your URL in there or use XmlDocument.LoadXml() to load the XML from a string.

You could use the XmlDocument.LoadXml class to read the received xml. There is no need to save it to disk.
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(receivedXMLStr);
//valid xml
}
catch (XmlException xe)
{
//invalid xml
}

Use Linq2Xml..
XElement doc;
try
{
doc=XElement.Load(yourStream);
}
catch
{
//invalid XML
}
foreach(XElement node in doc.Descendants())
{
node.Value;//value of this node
nodes.Attributes();//all the attributes of this node
}

Thanks all of you for your reply, i want to laod my XML without save it on a local Path, because saving creating many XML.
Finally i find the solutions for load the XML from class on a Memory stream, I thinn this solution is very easy and optimize
XmlDocument doc = new XmlDocument();
System.Xml.Serialization.XmlSerializer serializer2 = new System.Xml.Serialization.XmlSerializer(Patients.GetType());
System.IO.MemoryStream stream = new System.IO.MemoryStream();
serializer2.Serialize(stream, Patients);
stream.Position = 0;
doc.Load(stream);

You need to use the Deserialize option to read the xml. Follow the below steps to achieve it,
Create a target class. It structure should represent the xml output.
After creating the class, use the below code to load your xml into the target object
TargetType result = null;
XmlSerializer worker = new XmlSerializer(typeof(TargetType));
result = worker.Deserialize("<xml>.....</xml>");
Now the xml is loaded into the object 'result' and use it.

Related

XmlDocument in WCF Service method not successfully saving to file using the class' save method

Hello and thanks in advance,
I am attempting to take the input from text boxes in a silverlight application and on an event fired by a button click, convert them to an xml string, pass the string and a specified file name to a WCF service call and in that call save the xml to the specifed file(via a string parameter). The code which captures the text into an xml string seems to be successfully working(based on what I see in the variables when debugging) and looks like this:
private void ServerInfoNext_Click(object sender, RoutedEventArgs e)
{
//new RegisterServerGroupObject instance
RegisterServerGroupObject groupInfo= new RegisterServerGroupObject(groupNameTB.Text,1,parentServerNameTB.Text,LeaderNameCB.SelectedItem.ToString());
var serializer = new XmlSerializer(typeof(RegisterServerGroupObject));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("","");
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
settings.CloseOutput = true;
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb,settings))
{
serializer.Serialize(writer, groupInfo);
writer.Close();
}
//sb now contains the xml string with the information from the serialized class
string contentsString = sb.ToString();
//create instance of XmlWrite service
XMLWriteServiceClient xmlClient = new XMLWriteServiceClient();
xmlClient.WriteXmlToServerCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(xmlClient_WriteXmlToServerCompleted);
xmlClient.WriteXmlToServerAsync("ServerGroups.xml", contentsString);
}
at this point when the variable contents string is passed to the service method, I can see that it has valid xml, as well as within the service method itself, which looks like this:
public class XMLWriteService : IXMLWriteService
{
public void WriteXmlToServer(string filename,string xmlString)
{
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(xmlString.ToString());
try
{
xDoc.Save(filename);
}
catch (FileNotFoundException e)
{
Console.WriteLine(e.InnerException.ToString());
}
}
}
The try/catch block is not indicating that the file("ServerGroups.xml") is not found, and I currently have that xml file in the ClientBin of the server side portion of the project. (the .Web side). However, after the method terminates there is no new xml written to the file. Can someone please tell me what I am doing wrong? I don't know why the XmlDocument class instance is not saving its contents to the file. Thanks in advance!
You aren't passing a path, so it's just going to save the file to the current directory of the WCF service process, whatever that happens to be. Either find out what that is, or do a search on your whole server drive for that file name to see where it's saving it. Better yet, call Path.Combine to append a path to the begining of the file name before you save to it. For instance:
xDoc.Save(Path.Combine("C:\\ClientBin", filename));
To answer your question in the comment below, if you want to append the incoming XML data to the data that is already stored in the XML file on the server, that's a bit more involved. It all depends what the format of the XML is. Since you are using serialization, which by default will only allow one object per XML document (because it puts the object name as the root document element, of which there can only be one), then you would have to have a different XML format. For instance, on the server side, you would need to have some kind of root element on the document under which you could keep appending the incoming RegisterServerGroupObject objects. For instance, if your XML file on the server looked like this:
<?xml version="1.0" encoding="utf-8" ?>
<ListOfRegisterServerGroupObject>
</ListOfRegisterServerGroupObject>
Then, you could append the data by inserting new elements within that root element, like this:
<?xml version="1.0" encoding="utf-8" ?>
<ListOfRegisterServerGroupObject>
<RegisterServerGroupObject>
...
</RegisterServerGroupObject>
<RegisterServerGroupObject>
...
</RegisterServerGroupObject>
...
</ListOfRegisterServerGroupObject>
To do this, you would need to first load the XML document, then get the root element, then append the incoming XML as a child element. For instance:
public void WriteXmlToServer(string filename, string xmlString)
{
string filePath = Path.Combine("C:\\ClientBin", filename);
XmlDocument storage = New XmlDocument();
storage.Load(filePath);
XmlDocument incoming = New XmlDocument();
incoming.LoadXml(xmlString);
storage.DocumentElement.AppendChild(incoming.DocumentElement);
storage.Save(filePath);
}
You may need to 'map' the physical path to the output file within the service
string path = HostingEnvironment.MapPath("~/MyPath/MyFile.xml");

How to read XML document and display the output as string in c#

consider my source file looks like this.
<Content xmlns="uuid:4522eb85-0a47-45f9-8e2b-1x82c78xx920">
<first>Hello World.This is Fisrt field</first>
<second>Hello World.This is second field</second>
</Content>
I want to write a code, which read this xml document from a location and display it as string.
say name of the xml file is helloworld.xml.
Location: D:\abcd\cdef\all\helloworld.xml.
I have tried the following, but i was unable to do it.
XmlDocument contentxml = new XmlDocument();
contentxml.LoadXml(#"D:\abcd\cdef\all\helloworld.xml");
Response.Write("<BR>" + contentxml.ToString());
Response.write is displaying nothing. Correct me if i missed any thing. Its not creating any component and error is coming.
I have also tried this,
XmlDocument contentxml = new XmlDocument();
try
{
contentxml.LoadXml(#"D:\abcd\cdef\all\helloworld.xml");
}
catch (XmlException exp)
{
Console.WriteLine(exp.Message);
}
StringWriter sw = new StringWriter();
XmlTextWriter xw = new XmlTextWriter(sw);
contentxml.WriteTo(xw);
Response.Write("<BR>" + sw.ToString());
But i did not find the any output.
I want to read a XML file from a location and display it as it is as string.
Can anyone help on this.
Thank you,
Muzimil.
You need the OuterXml property:
Response.Write("<BR>" + contentxml.OuterXml);
Also you are loading a file not xml so use
contentxml.Load(#"D:\abcd\cdef\all\helloworld.xml");
instead of
contentxml.LoadXml(#"D:\abcd\cdef\all\helloworld.xml");
Do you really have to deserialize the XML at all? Why not just read it as a text file? Something like..
String text = File.ReadAllText(#"D:\abcd\cdef\all\helloworld.xml");
Response.Write(text);
With appropriate error handling obviously..
I would try using the XDocument class:
//load the document from file
var doc = XDocument.Load("..."); //== path to the file
//write the xml to the screen
Response.Write(doc.ToString());
If you want to use an XmlDocument instead, you would want to use Load instead LoadXml.
If you want to simply write a file to the output, you can do Response.WriteFile.
try this
XmlTextReader reader = new XmlTextReader (#"D:\abcd\cdef\all\helloworld.xml");
while (reader.Read())
{
Console.WriteLine(reader.Name);
}
Console.ReadLine();
String text = File.ReadAllText(Server.MapPath("~/App_Data/sample.xml"));
txtData.Text = text;

Trying to write to an existing XML file for C#

Thank you very much in advance
This is the original XML File
<my:Incident>
<my:Category>This is for Category</my:Category>
<my:Status>`Status is Close`</my:Status>
<my:Description>`This is the description part</my:Description>
</my:Incident>
and I would like to add other fields under my:Incident
This is an example of it:
<my:Incident>
<my:Category>This is for Category</my:Category>
<my:Status>`Status is Close`</my:Status>
<my:SummaryDescription>This is the summary</my:SummaryDescription>
<my:Description>`This is the description part</my:Description>
</my:Incident>
I tried to implemented but I got this error message:
The ':' character, hexadecimal value 0x3A, cannot be included in a name.
public void writerXMLTest(string fileName)
{
if (!File.Exists(fileName))
{
XmlTextWriter writer = new XmlTextWriter(fileName, null);
writer.WriteStartElement("my:Incident");
writer.WriteEndElement();
writer.Close();
}
XDocument doc = XDocument.Load(fileName);
XElement demoNode = new XElement("my:Incident");
demoNode.Add(new XElement("my:SummaryDescription", "Test Test"));
Console.WriteLine("I write it!!!!!");
}
I would appreciate if anyone can guide me where I did wrong in my code.
I modified the code a little. But now I'm not able to write it to the existing XML File
This is my code:
public void writerXMLTest(string fileName)
{
if (!File.Exists(fileName))
{
XmlTextWriter writer = new XmlTextWriter(fileName, null);
writer.WriteStartElement("Incident", "my");
writer.WriteEndElement();
writer.Close();
}
XDocument doc = XDocument.Load(fileName);
XElement demoNode = new XElement("SummaryDescription", "Test Test");
Console.WriteLine("I write it!!!!!");
}
This is wrong:
writer.WriteStartElement("my:Incident");
This is right:
writer.WriteStartElement("Incident", "blablablaSpace:my");
Edit:
writer.WriteStartElement("Incident", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2005-09-22T20:42:56:my");
There are several problems here. First your "original XML" is not valid because you have not defined the "my" namespace. Either you have not shown us the entire XML file, or you are hand-coding invalid XML. Don't do that.
I'm not able to write it to the existing XML File.
What does "I'm not able" mean? It throws an exception? What is the exception? Or do you mean your file is unchanged after running your code? That is unsurprising because your code doesn't actually do anything.
XDocument doc = XDocument.Load(fileName);
This loads your XML file from disk... and then does nothing with it. It doesn't change the file.
XElement demoNode = new XElement("SummaryDescription", "Test Test");
This creates a new XML element, totally unrelated to doc, the original file, or to anything else... and then throws it away without doing anything with it. You have not added it anywhere or saved anything to a file.
and I would like to add other fields under my:Incident
If you want to add demoNode to the file, you first must find the Incident node:
XElement e = doc.Descendants(XName.Get("Incident", nameSpace)).FirstOrDefault<XElement>();
Add your new element to it:
if (e != null)
{
e.Add( new XElement(XName.Get("SummaryDescription", nameSpace), "Test Test") );
}
Then save the changed document
doc.Save(fileName);
Your "my:" prefix is a namespace. You must use TagName = "Incident", Namespace="my".
Microsoft provides documentation on using XmlTextWriter with namespaces
http://msdn.microsoft.com/en-us/library/cfche0ka(v=vs.80).aspx

An error occurred while parsing EntityName

I'm trying to load a xml document into an object XPathDocument in C#.
My xml documents include this line:
trés dégagée + rade
and when the parser arrives there it gives me this error:
"An error occurred while parsing EntityName"
I know that's normal cause of the character "é". Does anybody know how can I avoid this error... My idea is to insert into the xml document an entities declaration and after replace all special characters with entities...but it's long and I’m not sure if it's working. Do you have other ideas? Simpler?
Thanks a lot
Was about to post this and just then the servers went down. I think I've rewritten it correctly from memory:
I think that the problem lies within the fact that by default the XPathDocument uses an XmlTextReader to parse the contents of the supplied file and this XmlTextReader uses an EntityHandling setting of ExpandEntities.
In other words, when you rely on the default settings, an XmlTextReader will validate the input XML and try to resolve all entities. The better way is to do this manually by taking full control over the XmlReaderSettings (I always do it manually):
string myXMLFile = "SomeFile.xml";
string fileContent = LoadXML(myXMLFile);
private string LoadXML(string xml)
{
XPathDocument xDoc;
XmlReaderSettings xrs = new XmlReaderSettings();
// The following line does the "magic".
xrs.CheckCharacters = false;
using (XmlReader xr = XmlReader.Create(xml, xrs))
{
xDoc = new XPathDocument(xr);
}
if (xDoc != null)
{
XPathNavigator xNav = xDoc.CreateNavigator();
return xNav.OuterXml;
}
else
// Unable to load file
return null;
}
Typically this is caused by a mismatch between the encoding used to read the file and the files actually encoding.
At a guess I would say the file is UTF-8 encoded but you are reading it with a default encoding.
Try beefing up your question with more details to get a more definitive answer.

How to Update a XML Node?

It is easy to read an XML file and get the exact Node Text, but how do I Update that Node with a new value?
To read:
public static String GetSettings(SettingsType type, SectionType section)
{
XmlTextReader reader = new XmlTextReader(HttpContext.Current.Request.MapPath(APPSETTINGSPATH));
XmlDocument document = new XmlDocument();
document.Load(reader);
XmlNode node = document.SelectSingleNode(
String.Format("/MyRootName/MySubNode/{0}/{1}",
Enum.Parse(typeof(SettingsType), type.ToString()),
Enum.Parse(typeof(SectionType), section.ToString())));
return node.InnerText;
}
to write ...?
public static void SetSettings(SettingsType type, SectionType section, String value)
{
try
{
XmlTextReader reader = new XmlTextReader(HttpContext.Current.Request.MapPath(APPSETTINGSPATH));
XmlDocument document = new XmlDocument();
document.Load(reader);
XmlNode node = document.SelectSingleNode(
String.Format("/MyRootName/MySubNode/{0}/{1}",
Enum.Parse(typeof(SettingsType), type.ToString()),
Enum.Parse(typeof(SectionType), section.ToString())));
node.InnerText = value;
node.Update();
}
catch (Exception ex)
{
throw new Exception("Error:", ex);
}
}
Note the line, node.Update(); does not exist, but that's what I wanted :)
I saw the XmlTextWriter object, but it will write the entire XML to a new file, and I just need to update one value in the original Node, I can save as a new file and then rename the new file into the original name but... it has to be simpler to do this right?
Any of you guys have a sample code on about to do this?
Thank you
You don't need an "update" method - setting the InnerText property updates it. However, it only applies the update in memory. You do need to rewrite the whole file though - you can't just update a small part of it (at least, not without a lot of work and no out-of-the-box support).
XmlDocument.Load has an overload that will take the filename directly so there is no need for the reader.
Similarly when you are done XmlDocument.Save will take a filename to which it will save the document.
The nodeValue property can be used to change the value of a text node.
The following code changes the text node value of the first element:
Example:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];
x.nodeValue="Easy Cooking";
source: http://www.w3schools.com/DOM/dom_nodes_set.asp
You're updating the node in an in-memory representation of the xml document, AFAIK there's no way to update the node directly in the physical file. You have to dump it all back to a file.

Categories