Cannot replace child XmlDocument [duplicate] - c#

This question already has an answer here:
Error: "The node to be inserted is from a different document context"
(1 answer)
Closed 8 years ago.
I am using XML as discuss forum in ASP.NET. I am trying to add functionality for updating comments. My XML structure is this:
<forum>
<author id="1">
<comment id="0" idUser="19">
<name>....</name>
<date>....</date>
<message>...</message>
</comment>
<comment id="1" idUser="4">
....
</comment>
</author>
<author id="2">
....
</author>
</forum>
And my code is:
protected void btnEditComment_Click(object sender, EventArgs e)
{
if (messageTxb.Text!="" && nameTxb.Text!="")
{
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("~/App_Data/forum.xml"));
XmlNode newComment = (XmlNode)Session["Comment"];
XmlNode oldComment = doc.SelectSingleNode(string.Format("//author[#id={0}]/comment[#id={1}]",Request.QueryString["id"],newComment.Attributes["id"].Value));
newComment.ChildNodes[0].InnerText = nameTxb.Text.Trim();
newComment.ChildNodes[1].InnerText = string.Format("{0:D}", DateTime.Now);
newComment.ChildNodes[2].InnerText = messageTxb.Text.Trim();
oldComment.ParentNode.ReplaceChild(newComment, oldComment);
doc.Save(Server.MapPath("~/App_Data/forum.xml"));
Repeater1.DataBind();
Response.Redirect(string.Format("~/user/Autor.aspx?id={0}", Request.QueryString["id"]));
}
}
I get error
'The node to be inserted is from a different document context.'
It raises when I am trying to use the replaceChild method.

try to replace this row:
oldComment.ParentNode.ReplaceChild(doc.ImportNode(newComment, true), oldComment);

Related

how do i set an XML element replace on C#?

so I'm making an project and i been having a problem with a XML replacing some elements after getting from them a texts
i tried a lot of options remove add then new
and XML is like this:
<?xml version="1.0" encoding="utf-8"?>
<UserAccountData>
<user>
<username>Admin</username>
<password>Partyguest12</password>
<ID1>1<stats level="50" HP="1000" exp="250000" /></ID1>
</user>
<user>
<username>2</username>
<password>2</password>
<ID2>2<stats Level="1" HP="20" exp="0" /></ID2>
</user>
<user>
<username>3</username>
<password>3</password>
<ID3>3<stats Level="1" HP="20" exp="0" /></ID3>
</user>
<user>
<username>4</username>
<password>4</password>
<ID4>4<stats Level="1" HP="20" exp="0" /></ID4>
</user>
<user>
<username>5</username>
<password>5</password>
<ID5>5<stats Level="1" HP="20" exp="0" /></ID5>
</user>
</UserAccountData>
public partial class Game : MetroFramework.Forms.MetroForm
{
private void Save_data_Progress_Click(object sender, EventArgs e)
{
int IDcheck = 0;
XmlDocument User_Data_Exp_Use = new XmlDocument();
User_Data_Exp_Use.Load("UserData.xml");
foreach (XmlNode ID_Finder in User_Data_Exp_Use.SelectNodes("UserAccountData/user"))
{
IDcheck++;
if ((Account.Text == ID_Finder.SelectSingleNode("username").InnerText) && (Log_In_Data.PassKey == ID_Finder.SelectSingleNode("password").InnerText))
{
break;
}
}
XmlNode User_Path = User_Data_Exp_Use.SelectSingleNode("UserAccountData/user/ID" + IDcheck);
XmlElement Stats_Set = User_Data_Exp_Use.CreateElement("stats");
Stats_Set.SetAttribute("Level", Lv.Text);
Stats_Set.SetAttribute("HP", Hit_Points.Text);
Stats_Set.SetAttribute("exp",XP.Text);
User_Path.AppendChild(Stats_Set);
User_Data_Exp_Use.Save("UserData.xml");
}
}
it got me nothing or one of the XML error after run, saying its NULL

Reading in XML from WPF c#

I'm struggling to read in a "GPX" file to a WPF (c#) project. Sample GPX is provided below. I've tried a number of different options with the same result.
Document is loading ok, but I'm unable to break it down to access the Nodes Directly.
Any help would be greatly appreciated.
Thanks.
private void Simple_Click(object sender, RoutedEventArgs e)
{
XmlDocument xml = new XmlDocument();
xml.Load(#"C:\Users\Jonathon\Desktop\GPX_Data.gpx");
XmlNodeList nodes = xml.SelectNodes("trkpt"); // have tried: double '/' to get nodes at any level (XPath syntax)
//XmlNodeList nodes = xml.SelectNodes("/gpx/trk/trkseg/trkpt");
int count = 0;
foreach (XmlNode xn in nodes)
{
count++;
}
}
}
Sample GPX File
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="Endomondo.com"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1
http://www.topografix.com/GPX/1/1/gpx.xsd
http://www.garmin.com/xmlschemas/GpxExtensions/v3
http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd
http://www.garmin.com/xmlschemas/TrackPointExtension/v1
http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<author>
<name>Jonathon Ralfe</name>
<email id="jonathon" domain="ralfe.net"/>
</author>
<link href="http://www.endomondo.com">
<text>Endomondo</text>
</link>
<time>2015-01-27T18:31:26Z</time>
</metadata>
<trk>
<src>http://www.endomondo.com/</src>
<link href="https://www.endomondo.com/workouts/463986953/2256850">
<text>endomondo</text>
</link>
<type>SKIING_DOWNHILL</type>
<trkseg>
<trkpt lat="45.576892" lon="6.894079">
<time>2015-01-26T09:49:57Z</time>
</trkpt>
<trkpt lat="45.576892" lon="6.894079">
<ele>1595.0</ele>
<time>2015-01-26T09:49:59Z</time>
</trkpt>
<trkpt lat="45.577109" lon="6.893946">
<ele>1581.0</ele>
<time>2015-01-26T09:51:46Z</time>
</trkpt>
<trkpt lat="45.5772" lon="6.894084">
<ele>1575.0</ele>
<time>2015-01-26T09:52:02Z</time>
</trkpt>
<trkpt lat="45.577247" lon="6.894212">
<ele>1577.0</ele>
<time>2015-01-26T09:52:05Z</time>
</trkpt>
<trkpt lat="45.577317" lon="6.89452">
<ele>1589.0</ele>
<time>2015-01-26T09:52:11Z</time>
</trkpt>
That's because your xml contains namespaces, so you have to set namespace when querying data.
Consider this approach:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("x", "http://www.topografix.com/GPX/1/1");
XmlNodeList nodes = xml.SelectNodes("//x:trkpt", nsmgr);
Here we're creating NamespaceManager, setting namespace according to your data xmlns="http://www.topografix.com/GPX/1/1" attribute and using this namespace in XPath.
By XPath selection:
foreach(XElement aElement in xml.XPathSelectElements("/trk/trkseg").Elements())
{
foreach(XNode aXNode in aElement.Nodes())
{
//Access subnodes of trkpt
}
}

Validation of Docbook 5.0 XML via XSD with C# .Net

I try to validate a docbook 5.0 xml via c# and xsd data.
I started from the example here: http://msdn.microsoft.com/en-us/library/ckztbtx6(v=vs.110).aspx where it is pretty easy and simple.
I made the notValidXSD.xml (in the example) valid removing the first book calling it nowValidXSD.xml and it words fine.
Now I tried the same for the Docbook 5.0 format ( docbook.xsd, xml.xsd xlink.xml ) which you can download here http://www.docbook.org/xml/5.0/xsd/
Trying the code (given by the example on msdn above) gives me:
Validating XML file mydocxml.xml
Validation error: the http ://www.w3.org/XML/1998/namespace:id-Attribute is not declared.
Validation error: the http ://docbook.org/ns/docbook:article-Element is not declared.
Validation error: the schema informationen für das Attribute 'version' could not be found.
Validation error: the http://docbook.org/ns/docbook:title-Element is not declared.
Validation error: the http://docbook.org/ns/docbook:para-Element is not declared.
Validation finished. Validation failed.
(I had to make spaces after http because its my first question here)
I don't know what to do any more. For me the files look fine. I tried Googling the problem for hours now and can't seem to be able to validate via c#.
Here are the files:
<!-- nowValidXSD.xml -->
<?xml version='1.0' encoding="UTF-8"?>
<bookstore xmlns="urn:bookstore-schema"
xmlns:xsi="http ://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:bookstore-schema books.xsd">
<book genre="novel">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
</bookstore>
And the docbook xml:
<!-- mydocxml.xml -->
<?xml version="1.0" encoding="UTF-8"?> <!-- -->
<article xmlns="http ://docbook.org/ns/docbook" version="5.0"
xmlns:xsi="http ://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http ://docbook.org/ns/docbook docbook.xsd">
<title>some title</title>
<para> some text.</para>
</article>
The problem was that XmlValidatingReader is not only obsolete it is also not doing what is is supposed to be doing.
I post my new Validation method basically from here: http://msdn.microsoft.com/en-US/library/as3tta56(v=vs.80).aspx in hopes that is helps someone :)
private Boolean m_success = true;
private void ValidationCallBack(object sender, ValidationEventArgs args)
{
m_success = false;
Console.WriteLine("\r\n\tValidation error: " + args.Message);
}
public void validate(string xmlfile, string ns, string xsdfile)
{
m_success = true;
XmlReaderSettings settings = new XmlReaderSettings();
XmlSchemaSet sc = new XmlSchemaSet();
sc.Add(ns, xsdfile);
settings.ValidationType = ValidationType.Schema;
settings.Schemas = sc;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
XmlReader reader = XmlReader.Create(xmlfile, settings);
// Parse the file.
while (reader.Read()) ;
Console.WriteLine("Validation finished. Validation {0}", (m_success == true ? "successful!" : "failed."));
reader.Close();
}

XmlDocument and getting specific Attributes using xPath

I have seen a couple of examples on here where Xpath is used in conjunction with XmlDocument to get a specific attribute from an XmlDocument Node.... Example
Console.WriteLine(xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/#name").Value.ToString());
For some reason I am getting a "Object reference not set to an instance of an object." exception. Whenever I run across that particular line of code. I have a little test app that I have set up to test out different things before I put them into my main project...
Here is the code for that...
namespace ReadXml
{
class Program
{
static void Main(string[] args)
{
//string fulXmlPath = System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/templateExample.xml");
XDocument xDocument = XDocument.Load("C:\\Users\\derekww\\Documents\\XML Documents\\templateExample.xml");
XElement elem = xDocument.Element("dataTemplateSpecification"); ;
XmlDocument xmlDocument = new XmlDocument();
StreamReader file = new StreamReader("C:\\Users\\derekww\\Documents\\XML Documents\\templateExample.xml");
xmlDocument.Load(file);
//XmlDocument theDoc = new XmlDocument();
//using (var xmlReader = xDocument.CreateReader())
//{
// xmlDocument.Load(xmlReader);
//}
//Console.WriteLine(elem.ToString());
XmlNode xNode = xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element");
Console.WriteLine("WORK PLEASE!!!! {0}", xNode.Value.ToString());
//Console.WriteLine(xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/#name").Value.ToString());
//Console.WriteLine("This better Work>>>> {0}", xmlDocument.Attributes["/dataTemplateSpecification/templates/template/elements/element/#name"].Value);
Console.ReadLine();
//Console.WriteLine("This better Work>>>> {0}", xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/#name").Value);
//foreach (String AttVal in xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/#name").Value)
{
//Console.WriteLine("This better Work>>>> {0}", AttVal);
}
}
}
}
Here is part of the XML that I used...
<?xml version="1.0" encoding="utf-8"?>
<dataTemplateSpecification id="id1" name="name1" xmlns="http://EADIS.upmc.com /DataTemplateSpecification.xsd">
<description xmlns="">
<html>text</html>
</description>
<templates xmlns="">
<template>
<elements>
<element id="element0" name="PatientId" display="Patient ID" dataType="String" value="0101010111111" visable="false" readOnly="true">
<validation>
<rules>
<rule id="0" test="#element0.value == ''">
<fail>
<html><b>Patient ID is null, value must be present</b></html>
</fail>
</rule>
</rules>
</validation>
</element>
</elements>
</template>
<templates>
I just showed you the part that you need to understand the xml structure. I assure you that it is well formed. I think I asked this question before but somehow or the other it didn't get posted (maybe I forgot, who knows). Any help with this would be greatly appreciated. If I come up with a reason for why it isn't working I will be sure to let you guys know.
Thank You.
Why can't you use this XPath:
xmlDocument.SelectSingleNode("//templates/template/elements/element/#name").Value
You need to specify the namespace of the XML file in your code.
See here for more info: How to select xml root node when root node has attribute?

XPath not working as expected

I have an XML document in this format:
<?xml version="1.0" encoding="utf-8" ?>
<SupportedServices>
<Service>
<name>Google Weather</name>
<active>Yes</active>
</Service>
...
</SupportedServices>
And I'm trying to parse the XML file like so:
public void InitializeDropDown(string XmlFile, string xpath)
{
XmlDocument doc = new XmlDocument();
doc.Load(XmlFile);
var rootNode = doc.DocumentElement;
var serviceList = rootNode.SelectNodes(xpath);
Parallel.ForEach(serviceList.Cast<XmlNode>(), service =>
{
if (Properties.Settings.Default.ServiceActive &&
Properties.Settings.Default.ServiceName == service.InnerText)
{
WeatherServicesCBO.Items.Add(service.InnerText);
}
});
}
The issue I'm having is both values (name & active) are selected so it would look like Google WeatherYes, when All I'm wanting is Google Weather. Can someone tell me what's wrong with my XPath (which is here):
InitializeDropDown("SupportedWeatherServices.xml", "descendant::Service[name]");
The XPath should be //Service/name
var serviceList = rootNode.SelectNodes("//Service/name");
or descendant::Service/name, if you like this syntax more.

Categories

Resources