XDocument won't save to file - c#

Trying to write some simple code and see if I can get a hang of this XML business.
public static void Save() {
XDocument doc = XDocument.Load("Repository/Test.xml");
foreach (Produs p in produse) {
// Yes there are multiple elements ('p'), have checked
XElement root = new XElement("Produs");
root.Add(new XElement("Name", p.getName()));
root.Add(new XElement("Quantity", p.getQuant().ToString()));
doc.Element("Produse").Add(root); // This "Produse" here should be the root element of the XML file, right ?
//doc.Save("Repository/Test.xml");
}
doc.Save("Repository/Test.xml"); // moved here
}
No compile, or run time error, but nothing gets changed within the file. I do read from the file, so it does work.
Extra info on the .xml file (within visual studio):
Build action: Content
Copy to output directory: Copy always

Related

Appending inside a parent tag using XmlWriter

I am using this code to write to a xml document. Issue is every time I call this code it overrides previously written Tags element.
However I want to append multiple Tag elements inside the Tags elements. How can I make such sets using XmlWriter?
using (XmlWriter writer = XmlWriter.Create(path))
{
writer.WriteStartElement("Tags");
writer.WriteElementString("Tag", tagName);
writer.WriteEndElement();
}
I found out over the net few solution involving LINQ, with which I am not very good at. So I am looking something without it?
This can be done via Linq Xml by:
public void AddTagToXml(string path, string tag)
{
XDocument doc;
// Load the existing file
if (File.Exists(path)) doc = XDocument.Load(path);
else
{
// Create a new file with the parent node
doc = new XDocument(new XElement("Tags"));
}
doc.Root.Add(new XElement("tag", tag));
doc.Save(path);
}
It's not terribly efficient as the file is opened and saved on each function call, but it covers your requirements.

Can not save string / node to XML WP8

I am reading the contents of an xml file perfectly into a longlistselector with tap events attached. All working great. The file sits in the main assets folder of the project.
Now i would also like to add strings/ nodes to my simple XML, but for some reason i can't find the right syntax to save it to the file.
My xml file looks like:
<?xml version="1.0" encoding="utf-8" ?>
<phrases>
<item><name>What is your name?</name></item>
<item><name>How old are you?</name></item>
</phrases>
Now I tried the following inside of a click event of a button:
XDocument xDoc = XDocument.Load("phrases.xml");
var contactsElement = new XElement("item",
new XElement("name", "blalllllaaaallaala")));
xDoc.Add(contactsElement);
xDoc.Save("phrases.xml");
VS2013 tells me that the xDoc.Save("phrases.xml") has invalid arguments. When i read from that file i provide the same path, so i dont understand what is expected here? Please give some suggestions.
Just try out with this snippet...
// load original XML from the stream
XDocument loadedData = XDocument.Load(stream);
// create a new parent XML structure (new root) and load the original nodes
var newXml = new XDocument(new XElement("Histories"));
newXml.Root.Add(loadedData.Root);
// create the new node
var contactsElement = new XElement("item",
new XElement("name", "blalllllaaaallaala")));
NewNode.Add(contactsElement);
// add the new node
newXml.Root.Add(NewNode);
// save the stream
newXml.Save(stream);
For more have a look here too.

how to modify a .plist file using c#?

how to change the 14th line as changed value, And then save it as .plist file! i am trying to use XmlElement and then save it, but the problem is after i save that file, the doctype line will be ,I mean the "[]" has been added at the end of doctype line which will cause issue when iPhone use this file.in c#, how to edit it in right way?
i use below code to modify .plist file:
XmlDocument doc = new XmlDocument();
string plistPath = "app.plist";
doc.Load(plistPath);
foreach (var node in doc.SelectNodes("//string"))
{
if (node is XmlElement)
{
var elem = (XmlElement)node;
if (elem.InnerText == "software-package")
{
var versionElement = elem.NextSibling.NextSibling as XmlElement;
if (versionElement != null)
{
versionElement.InnerText = "PCDownload Url";
}
}
}
}
doc.Save(plistPath);
and the DOCTYPE line will changed to:< !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"[]> in .plist file.
I think your issue has to do with the XmlDocument.Save() method. As you already know, XML and plist files are slightly different, but the Save() method is trying to apply XML properties to your plist when saving.
Here are some options:
1) Use regular expressions. Buffer the file contents into a byte[], make your changes using regular expressions, and then write that buffer to .plist.
2) Parse the document using the XML parser, but don't use the built in Save() method. This may still result in unwanted modifications in the plist file, but it's worth a shot.
My solution was to search and replace this string and remove it using another command. Not very efficient, but gets the job done:
...
doc.Save(plistPath);
(Get-Content -path $plistPath -Raw) -replace '"\[\]>', '' | Set-Content -Path $plistPath
Check out this link as well to do the same for android and iOS:
https://gist.github.com/campbellja/e5d735f048cab76adb16957fe4a7ad75

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");

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

Categories