C# Delete Item from XML List - c#

i write some UWP app. There i want to save/Update/Delete in a XML List. My XML List Looks like:
<?xml version="1.0" encoding="utf-8"?>
<rootnode>
<Kunde Name="Testkunde" />
<Kunde Name="Testkunde2" />
</rootnode>
If i want to remove a item with this code
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(#"C:\Users\IT\source\repos\App3\App3");
StorageFile file = await folder.GetFileAsync("Kundenliste.xml");
using (IRandomAccessStream writeStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
Stream s = writeStream.AsStreamForWrite();
XDocument doc = XDocument.Load(s);
var q = from node in doc.Descendants("Kunde")
let attr = node.Attribute("Name")
where attr != null && attr.Value == "Testkunde"
select node;
q.ToList().ForEach(x => x.Remove());
doc.Save(s);
}
This happens
<?xml version="1.0" encoding="utf-8"?>
<rootnode>
<Kunde Name="Testkunde" />
<Kunde Name="Testkunde2" />
</rootnode><?xml version="1.0" encoding="utf-8"?>
<rootnode>
<Kunde Name="Testkunde2" />
</rootnode>
anyone can help me?

Just set
s.Position = 0;
s.SetLength(0);
after
Stream s = writeStream.AsStreamForWrite();
XDocument doc = XDocument.Load(s);
and it will works

Related

Why is xml declaration getting deleted while parsing?

I'm trying to modify some node value from one xml file to another using the below program which gets the value from the first node pub-title from a xml file in a folder called abc and then pastes the value to the first node publisher-name in another xml file in a folder named xyz.
NOTE: The escape_string method is implemented to not modify the UTF-8 entity values and keep them as they are.
var job_folders = Directory.EnumerateDirectories(textBox1.Text, "*", SearchOption.TopDirectoryOnly);
foreach (string job_folder in job_folders)
{
var target_xml_file = Directory.GetFiles(job_folder, "*.xml", SearchOption.AllDirectories).Where(a => Path.GetFileName(Path.GetDirectoryName(x)).ToLower() == "abc").First();
var target_meta_file = Directory.GetFiles(job_folder, "*.xml", SearchOption.AllDirectories).Where(a => Path.GetFileName(Path.GetDirectoryName(x)).ToLower() == "xyz").First();
string path = Path.GetFullPath(target_meta_file);
string file_content = escape_string(File.ReadAllText(path), 0);
XDocument doc = XDocument.Parse(file_content, LoadOptions.PreserveWhitespace);
var lbl=doc.Descendants("pub-title").First().Value;
XDocument doc2 = XDocument.Parse(escape_string(File.ReadAllText(target_xml_file), 0), LoadOptions.PreserveWhitespace);
doc2.DocumentType.InternalSubset = null;
doc2.Descendants("publisher-name").First().Value=lbl;
doc2.Save(target_xml_file);
File.WriteAllText(target_xml_file, escape_string(doc2.ToString(), 1));
}
MessageBox.Show("Complete");
private static string escape_string(string input_string, int option)
{
switch (option)
{
case 0:
return input_string.Replace("&", "&").ToString();
case 1:
return input_string.Replace("&", "&").ToString();
default:
return null;
}
}
Everything goes fine but <?xml version="1.0" encoding="utf-8"?> is getting deleted from the file in target_xml_file.
How do I fix this?
File before modification
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="jats-html.xsl"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD with OASIS Tables v1.0 20120330//EN" "JATS-journalpublishing-oasis-article1.dtd"[]>
<article article-type="proceedings" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:oasis="http://www.niso.org/standards/z39-96/ns/oasis-exchange/table">
<front>
<journal-meta>
<journal-id journal-id-type="publisher-id" />
<journal-title-group>
<journal-title>Eleventh & Tenth International Conference on Correlation Optics</journal-title>
</journal-title-group>
<issn pub-type="epub">0277-786X</issn>
<publisher>
<publisher-name>SPIE</publisher-name>
</publisher>
</journal-meta>
....
....
File after
<?xml-stylesheet type="text/xsl" href="jats-html.xsl"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD with OASIS Tables v1.0 20120330//EN" "JATS-journalpublishing-oasis-article1.dtd">
<article article-type="proceedings" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:oasis="http://www.niso.org/standards/z39-96/ns/oasis-exchange/table">
<front>
<journal-meta>
<journal-id journal-id-type="publisher-id" />
<journal-title-group>
<journal-title>Eleventh & Tenth International Conference on Correlation Optics</journal-title>
</journal-title-group>
<issn pub-type="epub">0277-786X</issn>
<publisher>
<publisher-name>a</publisher-name>
</publisher>
</journal-meta>
Following the answer to XDocument.ToString() drops XML Encoding Tag you should not use ToString method, use StringWriter instead:
using (var stream = new MemoryStream())
{
using (var writer = new XmlTextWriter(stream, Encoding.UTF8))
{
doc2.Save(writer);
}
string xml = escape_string(Encoding.UTF8.GetString(stream.ToArray()), 1);
File.WriteAllBytes(target_xml_file, Encoding.UTF8.GetBytes(xml));
}
Why not simply add an XDeclaration method after the process, something like
new XDeclaration("1.0", "utf-8", null)
Then save the file. It takes only two lines of code.

After deleting element from the xml, XDocument adds a line at the end

I am deleting element from xml with this code below;
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile MyFile = await localFolder.GetFileAsync("CustomTV.xml");
var stream4 = await MyFile.OpenStreamForReadAsync();
XDocument myXml2 = XDocument.Load(stream4);
myXml2.Element("channelLists")
.Elements("channellist")
.Where(x => (string)x.Attribute("lname") == lnameselectedText)
.Remove();
using (var stream = await (await ApplicationData.Current.LocalFolder.CreateFileAsync("CustomTV.xml", CreationCollisionOption.OpenIfExists)).OpenAsync(FileAccessMode.ReadWrite))
{
myXml2.Save(stream.AsStreamForWrite());
}
before the delete the element with attribute "lname=name3";
<?xml version="1.0" encoding="utf-8"?>
<channelLists>
<channellist lname="name1" />
<channellist lname="name2" />
<channellist lname="name3" />
<channellist lname="name4" />
</channelLists>
after deletion;
<?xml version="1.0" encoding="utf-8"?>
<channelLists>
<channellist lname="name1" />
<channellist lname="name2" />
<channellist lname="name4" />
</channelLists>lname="name4"/> //It adds all the time this line with last elements attribute.
</channelLists>
What is the problem?
Looks like your code writes modified XML on top of the original XML. That's why you see reminder of the original XML which located beyond the extend of the modified XML :
lname="name4"/>
</channelLists>
That said, CreationCollisionOption.ReplaceExisting might be more appropriate in this case.

C# XDocument Save copy file and appends edited to end

When I'm trying to edit XML Element and save it, it generates copy (with edited element) and appends it to end of file.
var localStore = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream stream = new IsolatedStorageFileStream("DataFolder\\PlayerData.xml", FileMode.OpenOrCreate, FileAccess.ReadWrite, localStore);
var doc = XDocument.Load(stream);
doc.Root.Element("characters").Element("character").SetElementValue("expierence", 10);
doc.Save(stream, SaveOptions.None);
stream.Close();
Example output file:
<?xml version="1.0" encoding="utf-8"?>
<root>
<characters>
<character>
<expierence>0</expierence>
</character>
</characters>
</root><?xml version="1.0" encoding="utf-8"?>
<root>
<characters>
<character>
<expierence>10</expierence>
</character>
</characters>
</root>
That's exactly what you told it to do by passing FileMode.OpenOrCreate.
If you want to truncate any existing file, pass Create.
For more information, see the documentation.

XML document processing cant load file

I am writing an application where i need to pull information out of a XML Document.
My XML document is stored in my projects bin/ Debug file.
I cant get it working.
XML document named informationData:
<xml>
<information>
<name >stian</name>
<surname>Kruger</surname>
<tel>0825514302</tel>
<photo>1234JLJ.jpg</photo>
</information>
</xml>
my call code:
private void btnReadXML_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("informationData.xml");
XmlNodeList dataNodes = xmlDoc.SelectNodes("/information");
foreach (XmlNode node in dataNodes)
{
Name = node.SelectSingleNode("name").InnerText;
Surname = node.SelectSingleNode("surname").InnerText;
TelNumber = Convert.ToInt32(node.SelectSingleNode("tel").InnerText);
}
}
Your XPath selector is wrong. Replace:
XmlNodeList dataNodes = xmlDoc.SelectNodes("/information");
with:
XmlNodeList dataNodes = xmlDoc.SelectNodes("//information");
or with:
XmlNodeList dataNodes = xmlDoc.DocumentElement.SelectNodes("information");
Also make sure that the XML file is present in the same folder as the running executable (you said bin/Debug/informationData.xml). If the XML file is part of your Visual Studio project you could select it and in the properties set Copy to Output Directory to Copy if newer. This way VS will automatically copy the XML file to this output folder everytime you compile the project.
You can use this code
<?xml version="1.0" encoding="utf-8" ?>
<information>
<name >stian</name>
<surname>Kruger</surname>
<tel>0825514302</tel>
<photo>1234JLJ.jpg</photo>
</information>
var xmlDoc = XDocument.Load("informationData.xml");
var name = xmlDoc.Element("name").Value;
var surname = xmlDoc.Element("surname").Value;
var telNumber = Convert.ToInt32(xmlDoc.Element("tel").Value);
add <?xml version="1.0" encoding="utf-8"?> as first line in XML file

Treeview and list view control

I have following sample xml file
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<IResponse xmlns:xsi="http://www.w3.org/2001/XMLScheminstance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Language>en</Language>
<Code>Approved</Code>
<Message> Approved</Message>
<Info xsi:type="Info">
<Number>11</Number>
<ExpiryDate year="10" month="8" />
<StartDate year="7" month="8" />
<currency="GBP">36.00</currency>
<ACode>096392</ACode>
</IResponse>
How to display the nodes and child elemants in treeview control and values in the list view?
public void Deserialize()
{
XmlReader reader = XmlReader.Create(this.filePath);
XmlSerializer serializer = new XmlSerializer(typeof(Response));
if (serializer.CanDeserialize(reader))
{
Response obj = serializer.Deserialize(reader) as Response;
// obj consists of xml file nodes and i want to display this in treeview
// control and values in between them as list view .
}
else
{
iccTransactionResponseBindingSource.DataSource = null;
}
}
Maybe this MS KB document? http://support.microsoft.com/kb/317597

Categories

Resources