Need help in adding a new XML node - c#

<?xml version="1.0" encoding="utf-8"?>
<mappings>
<mapping>
<aID iskey="true">ABC</aID>
<bID iskey="true">DEF</bID>
<SubAccount>PS</SubAccount>
<Account>PS</Account>
</mapping>
<mapping>
<aID isKey="true">GHI</aID>
<bID isKey="true">PFP</bID>
<SubAccount>MS</SubAccount>
<!-- I want to add a new node here, how can I do this -->
</mapping>
<mapping>
<aID isKey="true">MNO</aID>
<bID isKey="true">BBG</bID>
<SubAccount>MAX</SubAccount>
</mapping>
</mappings>
I want to add a new node as mentioned in the above XML. I tried a lot but I could not succeed.
XmlDocument xDoc = new XmlDocument();
xDoc.Load(filename);
foreach (XmlNode node in xmlDoc.SelectNodes("/mappings/mapping"))
{
if (boothIDNode.InnerXml == BoothID)
{
chkBoothIDExists = true;
if (clientIDNode.InnerText == ClientID)
{
chkClientIDExists = true;
for (int j = 2; j < nodelist.Count; j++)
{
columnNode = nodelist[j];
if (columnNode.Name == column.ToString())
{
XmlNode elm = xDoc.CreateNode(XmlNodeType.Element,"Account",null);
elm.InnerText = value.ToString();
node.AppendChild(elm); // Error comes here
}
}
}
}
}
xmlDoc.Save(filename);
The question is solved. The problem occured due to my silly mistake. Basically there are two xml documnets and I'm creating a new node of other xml documnet due to which the error cames.
THanks all,
XmlDocument xDoc = new XmlDocument();
XmlDocument xmlDoc = new XmlDocument();
ERROR: The node to be inserted is from a different document context

Use something like this, not a c# person but this should help. I think insertafter is what you need:
XmlNode currNode = xDoc.SelectNodes("/mappings/mapping");
XmlNode elm = xDoc.CreateNode(XmlNodeType.Element,"Account",null);
currNode.InsertAfter(elm, currNode.LastChild);

In order to add a node, consider this example:
XDocument a = XDocument.Parse(#"<?xml version=""1.0"" encoding=""utf-8""?>
<mappings>
<mapping>
<aID iskey="true">ABC</aID>
<bID iskey="true">FPP</bID>
<SubAccount>PS</SubAccount>
<Account>PS</Account>
</mapping>
<mapping>
<aID isKey="true">GHI</aID>
<bID isKey="true">PFP</bID>
<SubAccount>MS</SubAccount>
<!-- I want to add a new node here, how can I do this -->
</mapping>
<mapping>
<aID isKey="true">MNO</aID>
<bID isKey="true">BBG</bID>
<SubAccount>MAX</SubAccount>
</mapping>
</mappings>");
a.Descendants("mapping").Skip(1).First().Add(new XElement("aaa", new XAttribute("id", 1)));
--->
<mappings>
<mapping>
<aID iskey="true">ABC</aID>
<bID iskey="true">FPP</bID>
<SubAccount>PS</SubAccount>
<Account>PS</Account>
</mapping>
<mapping>
<aID isKey="true">GHI</aID>
<bID isKey="true">PFP</bID>
<SubAccount>MS</SubAccount>
<!-- I want to add a new node here, how can I do this -->
<aaa id="1" />
</mapping>
<mapping>
<aID isKey="true">MNO</aID>
<bID isKey="true">BBG</bID>
<SubAccount>MAX</SubAccount>
</mapping>
</mappings>

XDocument doc = XDocument.Load(filepath); // filepath is string
doc.Element(firstnodename).SetElementValue(descendantname,newvalue); //names and value are string
doc.Save(filepath); // This line optional. And filepath like : #"C:\Users\user\desktop\a.xml" or "C:\\Users\\user\\desktop\\a.xml". You should write with ".
You can write longer .Element
ForEx:
doc.Element(firstnode).Element(secondnode).Element(thirdnode).SetElementValue(fourthnode,valueoffourth);

Related

Copy XML nodes to another XML includes child nodes

I need to create another xml whenever there is numerics in the zipname and move those related nodes to another xml
Actual XML :
<?xml version="1.0"?>
-<IMAGE date="20200603" Time="141511">
-<ZipFile name="something.zip" Date="06032020" Time="131511">
<name="015522000970" line="001" status="STORED" />
<name="015522000990" line="002" status="STORED" />
</ZipFile>
-<ZipFile name="something111.zip" Date="06032020" Time="131511">
<name="015522000970" line="001" status="STORED" />
<name="015522000990" line="002" status="STORED" />
</ZipFile>
</IMAGE>
Result xml (Newone need tobe created):
<?xml version="1.0"?>
-<IMAGE date="20200603" Time="141511">
-<ZipFile name="something111.zip" Date="06032020" Time="131511">
<name="015522000970" line="001" status="STORED" />
<name="015522000990" line="002" status="STORED" />
</ZipFile>
</IMAGE>
here is my code but it is not working . could anyone provide the approach how to copy
XmlNodeList xmlNodeList = xmlDoc.GetElementsByTagName(XML_ZIPFILETAG);
foreach (XmlNode node in xmlNodeList)
{
XmlDocument xmkdoc1 = new XmlDocument();
XmlNode copiedNode = xmlDoc.ImportNode(node,true);
//SelectSingleNode(#"/Image/ZipFileName");
// node.InnerXml;
XmlNode root = xmkdoc1.DocumentElement;
xmkdoc1.CreateElement("DocumentElemnet");
xmkdoc1.AppendChild(copiedNode);
}
You are quite close. When constructing the new document you need to build up the structure correctly. Try this (I did not test the code):
XmlDocument xmkdoc1 = new XmlDocument();
XmlNode root = xmkdoc1.createElement(XML_ZIPFILETAG);
xmkdoc1.AppendChild(root);
XmlNode copiedNode = xmlDoc.ImportNode(node,true);
root.AppendChild(copiedNode);

how to update a xml using a id in C#2.0

I am trying to update a xml on basis of id.
my xml file looks like this
<?xml version="1.0" standalone="yes"?>
<CATALOG>
<CD>
<ID>0</ID>
<HeaderDetailID>0</HeaderDetailID>
<FirstName>
</FirstName>
<LastName>
</LastName>
<EmployeeID>
</EmployeeID>
<Department>
</Department>
<Postion>
</Postion>
<Application>
</Application>
<Filter>
</Filter>
<AreaorCountryorStation>
</AreaorCountryorStation>
<NetworkDomain>
</NetworkDomain>
<Action>
</Action>
<NameOfController>
</NameOfController>
<Status>
</Status>
</CD>
<CD>
<ID>1</ID>
<HeaderDetailID>1</HeaderDetailID>
<FirstName>Basant</FirstName>
<LastName>Basant</LastName>
<EmployeeID>Basant</EmployeeID>
<Department>Basant</Department>
<Postion>Basant</Postion>
<Application>
</Application>
<Filter>
</Filter>
<AreaorCountryorStation>Basant</AreaorCountryorStation>
<NetworkDomain>Basant</NetworkDomain>
<Action>
</Action>
<NameOfController>Basant</NameOfController>
<Status>Request Completed</Status>
</CD>
</CATALOG>
Now I try to fetch id from hidden field and get It on server side to update the node name status.
for (int i = 0; i < DateData.Length - 1; i++)
{
string iRecordID = DateData[i];
XmlDocument xmlDoc = new XmlDocument();
string filepathsUpdate = Server.MapPath("Contact.xml");
xmlDoc.Load(filepathsUpdate);
XmlNode node = xmlDoc.SelectSingleNode("/CATALOG/CD[ID=" + DateData[i] + "]/Status");
node.InnerText = "Request Completed";
xmlDoc.Save(filepathsUpdate);
}
It works locally fine but on server it doesn't work.
Can I close the connection in XML file
I feel like xmlDoc.Save not working

Not able to get the element with XDocument

Below is the code i am using to get the value of the 'name'(attribute) of the 'person'
parameter tag="person" and parameter attribute="name"
public static string GetInformationFromXML(string tag,
string attribute,
string filePath)
{
XDocument doc = XDocument.Load(filePath);
string info = doc.Element(tag).Attribute(attribute).Value;
return info;
}
doc.Element(tag) is not getting the element even though when i expand doc, it does have an element with type 'Element' and Name 'person'
the file being read is XmlDocument for your information.
below is the xml of the file i am trying to read
<?xml version="1.0"?>
<import>
<company name1="ABC" name2="" action="create"
profile="\Profiles\ABC\" id="C1">
<address street="industrial" city="london"
country="england" id="A1">
<telecom type="phone" value="4839282992"
desc="" default="true" />
<telecom type="fax" value="3232" desc="" />
</address>
</company>
<person title="Mr." name="Tariq" surname="sheikh"
lang="EN" action="create" profile="Profiles\Tariq"
login="tariq" password="123456" default_address="A1">
<link reference="C1" type="Employee" description="Software developer" />
<address street="baker street" zip="12443"
city="london" country="england" />
<account bank="Barclays" account="4378734834" />
<telecom type="email" value="tariq.sheikh#abc.co.in" desc="" />
<registration type="temporaryID"
value="4623648c-739e-49c8-93fa-41dc7fed53ea" />
</person>
</import>
I am new to XDocument !
You have to use Descendants when element you're looking for is not direct child of current element (or root for XDocument).
string info = doc.Descendants(tag).First().Attribute(attribute).Value;

reading an xmlnode using xmlDocment

how can i read an Id from the below sample XML >>> CatalogItem Id="3212" and OrganizationName
string xmlfile = #"C:\Users\easwaranp\Desktop\test.xml";
ArrayList arrResult = new ArrayList();
string sContent = File.ReadAllText(xmlfile);
StringReader DocumentReader = new StringReader(sContent);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(DocumentReader);
XmlNodeList ReferenceNodes = xmlDoc.GetElementsByTagName("content:Topic");
foreach (XmlNode Node in ReferenceNodes)
{
string sTopicName = Node.ParentNode.ParentNode.Attributes["OrganizationName"].Value;
}
foreach (string s in arrResult)
{
Console.WriteLine(s);
}
Console.Read();
<content type="application/xml">
<CatalogItems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="sitename.xsd">
<CatalogSource Acronym="ABC" OrganizationName="ABC Corporation" />
<CatalogItem Id="32122" CatalogUrl="urlname">
<ContentItem xmlns:content="sitename.xsd" Title="Department 1">
<content:SelectionSpec ClassList="" ElementList="" />
<content:Language Value="eng" Scheme="ISO 639-2" />
<content:Source Acronym="ABC" OrganizationName="ABC Corporation1" />
<content:Topics Scheme="ABC">
<content:Topic TopicId="1" TopicName="Marketing1" />
<content:Topic TopicId="11" TopicName="Coverage1" />
</content:Topics>
</ContentItem>
</CatalogItem>
<CatalogItem Id="3212" CatalogUrl="urlname">
<ContentItem xmlns:content="sitename.xsd" Title="Department 2">
<content:SelectionSpec ClassList="" ElementList="" />
<content:Language Value="eng" Scheme="ISO 639-2" />
<content:Source Acronym="ABC" OrganizationName="ABC Corporation2" />
<content:Topics Scheme="ABC">
<content:Topic TopicId="2" TopicName="Marketing2" />
<content:Topic TopicId="22" TopicName="Coverage2" />
</content:Topics>
</ContentItem>
</CatalogItem>
<CatalogItem Id="32132" CatalogUrl="urlname">
<ContentItem xmlns:content="sitename.xsd" Title="Department 3">
<content:SelectionSpec ClassList="" ElementList="" />
<content:Language Value="eng" Scheme="ISO 639-2" />
<content:Source Acronym="ABC" OrganizationName="ABC Corporation3" />
<content:Topics Scheme="ABC">
<content:Topic TopicId="3" TopicName="Marketing3" />
<content:Topic TopicId="33" TopicName="Coverage3" />
</content:Topics>
</ContentItem>
</CatalogItem>
</CatalogItems>
</content>
using System;
using System.IO;
using System.Xml;
class GetValue{
public static void Main(){
var xmlDoc = new XmlDocument();
xmlDoc.Load("test.xml");
var xmlRoot = xmlDoc.DocumentElement;
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("content", "sitename.xsd");
var attr = xmlRoot.SelectSingleNode("descendant::content:Source/#OrganizationName[../../../#Id='3212']", nsmgr);
if(attr == null)
Console.WriteLine("not found!");
else
Console.WriteLine(attr.Value);
}
}
OUTPUT:
ABC Corporation2
XPath is your friend when it comes to tasks like this. I adapted the following code from a tutorial on codeproject.com. I don't know if it works (or will even compile), but it should get you started in the right direction. Also, I'm assuming your talking about C#, but in case I've misunderstood what language you're using, please disregard (a language tag on your question might help).
using System.Xml;
using System.Xml.XPath;
....
string fileName = "test.xml";
XPathDocument doc = new XPathDocument(fileName);
XPathNavigator nav = doc.CreateNavigator();
// Compile a standard XPath expression
XPathExpression expr;
idExpr = nav.Compile("/content/CatalogItems/CatalogItem/#id");
XPathNodeIterator iterator = nav.Select(idExpr);
// Iterate on the node set
try
{
while (iterator.MoveNext())
{
XPathNavigator nav2 = iterator.Current.Clone();
Console.WriteLine("id: " + nav2.Value);
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}

how to check if xml document has a certain list of attributes?

i am experimenting with C# and xml, i am trying to read a XML file i want to validate if "NumberOfDays" , "NumberOfBooks", "NumberOfExam", "CurrentDate" are existing, if missing. i want to add them with there values.
i have the following xmldocument :
<?xml version="1.0" encoding="utf-8" ?>
<MySample>
<Content>
<add key="NumberOfDays" value="31" />
<add key="NumberOfBooks" value="20" />
<add key="NumberOfExam" value="6" />
<add key="CurrentDate" value="15 - Jul - 2011" />
</Content>
</MySample>
i am writing a sample application in c# using
--------Edit--------
thank you AresAvatar for your responce.
but if the value exists i would like to update its value i.e. if let's say
<add key="NumberOfExam" value="" />
i want to change the value to 6
You can get a list of which nodes exist like this:
// Get a list of which nodes exist
XmlDocument doc = new XmlDocument();
doc.LoadXml(myXml);
List<string> existingNodes = new List<string>();
XmlNodeList bookNodes = doc.SelectNodes("/MySample/Content/add");
foreach (XmlNode nextNode in bookNodes)
{
foreach (XmlAttribute nextAttr in nextNode.Attributes)
existingNodes.Add(nextAttr.InnerText);
}
You can add missing nodes like this:
// Add nodes
XmlNode addRoot = doc.SelectSingleNode("/MySample/Content");
XmlElement addme = doc.CreateElement("add");
addme.SetAttribute("NumberOfDays", "31");
addRoot.AppendChild(addme);
You can set the value of existing nodes like this:
// Update a node
foreach (XmlNode nextNode in bookNodes)
{
foreach (XmlAttribute nextAttr in nextNode.Attributes)
{
switch (nextAttr.Name)
{
case "NumberOfDays":
((XmlElement)nextNode).SetAttribute("value", "31");
break;
// etc.
}
}
}
First of all, if you have control over the generated XML (if you make it yourself), avoid using this schema:
<?xml version="1.0" encoding="utf-8" ?>
<MySample>
<Content>
<add key="NumberOfDays" value="31" />
<add key="NumberOfBooks" value="20" />
<add key="NumberOfExam" value="6" />
<add key="CurrentDate" value="15 - Jul - 2011" />
</Content>
</MySample>
It's much easier to use with that schema:
<?xml version="1.0" encoding="utf-8" ?>
<MySample>
<Content>
<Adds>
<NumberOfDays>31<NumberOfDays/>
<NumberOfBooks>20<NumberOfBooks/>
<NumberOfExam>6<NumberOfExam/>
<CurrentDate>5 - Jul - 2011<CurrentDate/>
</Adds>
</Content>
</MySample>
And then:
XmlDocument doc = new XmlDocument();
doc.Load("YourXmlPath");
XmlNode firstNode = doc["MySample"];
if(firstNode != null)
{
XmlNode secondNode = firstNode["Content"];
if(secondNode != null)
{
XmlNode thirdNode = secondNode["Adds"];
if(thirdNode != null)
{
if(thirdNode["NumberOfDays"] == null) //The "NumberOfDays" node does not exist, we create it.
{
XmlElement newElement = doc.CreateElement("NumberOfDays");
newElement.InnerXml = 31;
thirdNode.AppendChild(newElement);
}
//Do the same for the other nodes...
}
}
}
doc.Save("YourXmlPath");
Just remember to check for null on every node, or put the whole block into a try/catch.
And to save the XML once you did your changes.
XmlDocument.Load() function loads the XML in memory, so you can check for any node without making "blind loops".

Categories