If I want to add, update or delete node in the xml using c#, how can it be done? My xml is shown below. I dont want transactionID node. I want to add a node called <Transformation>XML</Transformation> after corelationID node.
<?xml version="1.0" ?>
<GovTalkMessage xmlns="http://www.govtalk.gov.uk/CM/envelope">
<EnvelopeVersion>2.0</EnvelopeVersion>
<Header>
<MessageDetails>
<Class>HMRC-VAT-DEC</Class>
<Qualifier>poll</Qualifier>
<Function>submit</Function>
<TransactionID />
<CorrelationID>1B93D48C02D740C6B79DE68A27F3ADE5</CorrelationID>
<ResponseEndPoint PollInterval="10">https://secure.dev.gateway.gov.uk/poll</ResponseEndPoint>
<GatewayTimestamp>2011-04-05T07:41:43.018</GatewayTimestamp>
</MessageDetails>
<SenderDetails />
</Header>
<GovTalkDetails>
<Keys />
</GovTalkDetails>
<Body />
</GovTalkMessage>
The easiest thing to use would be LINQ to XML. For example:
XDocument doc = XDocument.Load("file.xml");
XNamespace ns = "http://www.govtalk.gov.uk/CM/envelope";
// Remove TransationID
XElement transactionElement = doc.Descendants(ns + "TransactionID").Single();
transactionElement.Remove();
// Add XML:
XElement correlationElement = doc.Descendants(ns + "CorrelectionID").Single();
XElement newElement = new XElement(ns + "XML");
correlationElement.AddAfterSelf(newElement);
// Save back
doc.Save("new-file.xml");
//Load the XML
XmlDocument documentXML = new XmlDocument();
documentXML.Load(Server.MapPath("AddDeleteUpdate.xml"));
XmlNamespaceManager xmlns = new XmlNamespaceManager(documentXML.NameTable);
xmlns.AddNamespace("bk", "http://www.govtalk.gov.uk/CM/envelope");
//Identify the parent node i.e <MessageDetails>
XmlNode nodeMessage = documentXML.SelectSingleNode("//bk:GovTalkMessage/bk:Header/bk:MessageDetails", xmlns);
//Delete the node.
XmlNode nodeTransactionID = documentXML.SelectSingleNode("//bk:GovTalkMessage/bk:Header/bk:MessageDetails/bk:TransactionID", xmlns);
nodeMessage.RemoveChild(nodeTransactionID);
//Create the new XML noded to be added.
XmlNode controlAttrNode = null;
controlAttrNode = documentXML.CreateElement("Transformation");
controlAttrNode.InnerText = "XML";
controlAttrNode.Attributes.RemoveAll();
//Get the node object to where it need to be added.
XmlNode nodeCorrelation = documentXML.SelectSingleNode("//bk:GovTalkMessage/bk:Header/bk:MessageDetails/bk:CorrelationID", xmlns);
//Insert the node after.
nodeMessage.InsertAfter(controlAttrNode, nodeCorrelation);
documentXML.Save(Server.MapPath("AddDeleteUpdate.xml"));
You'll need
XMLNode.InsertAfter(newChildNode,referenceChildNode)
This should kickstart you:
http://msdn.microsoft.com/en-US/library/system.xml.xmlnode.insertafter%28v=VS.80%29.aspx
Related
I'm trying to write a XML-document programatically.
I need to add <xsd:schema> tag to my document.
Currently I have:
var xmlDoc = new XmlDocument();
var root = xmlDoc.CreateElement("root");
xmlDoc.AppendChild(root);
var xsdSchemaElement = xmlDoc.CreateElement("schema");
xsdSchemaElement.Prefix = "xsd";
xsdSchemaElement.SetAttribute("id", "root");
root.AppendChild(xsdSchemaElement);
However, this renders to:
<root>
<schema id="root" />
</root>
How do I get the tag to be <xsd:schema>?
Already tried var xsdSchemaElement = xmlDoc.CreateElement("xsd:schema"); which simply ignores the xsd:.
Edit #1
Added method
private static XmlSchema GetTheSchema(XmlDocument xmlDoc)
{
var schema = new XmlSchema();
schema.TargetNamespace = "xsd";
return schema;
}
which is called like xmlDoc.Schemas.Add(GetTheSchema(xmlDoc)); but does not generate anything in my target XML.
Using LINQ-to-XML, you can nest XElements and XAttributess in a certain hierarchy to construct an XML document. As for namespace prefix, you can use XNamespace.
Notice that every namespace prefix, such as xsd in your case, has to be declared before it is used, something like xmlns:xsd = "http://www.w3.org/2001/XMLSchema".
XNamespace xsd = "http://www.w3.org/2001/XMLSchema";
var doc =
new XDocument(
//root element
new XElement("root",
//namespace prefix declaration
new XAttribute(XNamespace.Xmlns+"xsd", xsd.ToString()),
//child element xsd:schema
new XElement(xsd + "schema",
//attribute id
new XAttribute("id", "root"))));
Console.WriteLine(doc.ToString());
output :
<root xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:schema id="root" />
</root>
I want to replace following #eleval2,#eleval4 parameters with some other values using c#.net.Please help me to do it.
<root>
<element1>
<element2>
#eleval2
</element2>
</element1>
<element3>
<element4>
<element4>
#eleval4
</element4>
</element4>
</element3>
Directly updating node:
XmlDocument xml = new XmlDocument();
xml.Load("file_name.xml");
xml.SelectSingleNode("/root/element1/element2").InnerText = "NewValue";
For looping:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("path_here");
XmlNodeList tagNodes= xmlDoc.GetElementsByTagName("tag_of_your_interest");
//Loop through first child of above list
foreach (XmlNode chapter in tagNodes[0].ChildNodes)
{
//Perform your updates here
}
Load from string:
XmlDocument doc = new XmlDocument();
doc.LoadXml(str);
Get all list of nodes matches path:
XmlNodeList xnList = doc.SelectNodes("/sections/notebooks/article");
I'm trying to change a the value for the model atribute from the following .xml file.
<MTConnectDevices xmlns="urn:mtconnect.org:MTConnectDevices:1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mtconnect.org:MTConnectDevices:1.1 http://www.mtconnect.org/schemas/MTConnectDevices_1.1.xsd">
<Header version="1.1" sender="Company MTConnect Instance" creationTime="2010-08-26T19:00:47-07:00" instanceId="2" bufferSize="131072" />
<Devices>
<Device name="XX" iso841Class="1" uuid="000" id="id1001">
<Description manufacturer="name" serialNumber="Serial Number" model="UNDEFINED">
</Description>
This is what I've tried but it's not working as it's not changing the value for model.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(mypath);
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
var node = xmlDoc.SelectSingleNode("/ns:MTConnectDevices/ns:Header/ns:Devices/ns:Device/ns:Description", nsmgr);
node.Attributes["model"].Value = "changed";
xmlDoc.Save(mypath);
Can anyone give me a hand and tell me how to fix this?
Your xml contains namespaces, so you have to use them while retrieving node.
It can be done something like this:
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
var node = xmlDoc.SelectSingleNode("/ns:MTConnectDevices/ns:Devices/ns:Device/ns:Description", nsmgr);
I'm trying to parse the following:
<?xml version="1.0" encoding="utf-8"?>
<GC>
<CREATED>01/23/2014 16:10:18</CREATED>
<DATA>
<CONTAINER name="home" type="xml" version="1.1.0.0">
<HEADER>
<ATTRIBUTE name="lang" value="EN" />
<ATTRIBUTE name="destination" value="UK" />
</HEADER>
</CONTAINER>
</DATA>
</GC>
How do I go about finding the value when name="lang"?
So far I have this:
XmlDocument Doc = new XmlDocument();
Doc.Load(#path);
XmlNode node = Doc.DocumentElement.SelectSingleNode("/GC/DATA/CONTAINER/HEADER/ATTRIBUTE/NAME");
string SI = node.Attributes["lang"].InnerText;
Doesn't seem to work unfortunately, could use some help. Many thanks.
This will do it:
XmlNode node =
Doc.SelectSingleNode("/GC/DATA/CONTAINER/HEADER/ATTRIBUTE[#name = 'lang']/#value");
string SI = node.InnerText;
And I would advise using a null check:
XmlNode node =
Doc.SelectSingleNode("/GC/DATA/CONTAINER/HEADER/ATTRIBUTE[#name = 'lang']/#value");
string SI = null;
if(node != null)
{
SI = node.InnerText;
}
With using LINQ to XML you can get it like this:
XDocument xDoc = XDocument.Load("path");
var element = xDoc.Descendans("ATTRIBUTE").First();
var nameAttribute = (string)element.Attribute("name");
This will get you the value of the attribute in the ATTRIBUTE tag which has name == lang:
XmlDocument Doc = new XmlDocument();
Doc.Load(#path);
XmlNode node = Doc.DocumentElement.SelectSingleNode("/GC/DATA/CONTAINER/HEADER/ATTRIBUTE[#name='lang']");
string SI = node.Attributes["value"].InnerText;
XmlNode node = Doc.DocumentElement.SelectSingleNode("/GC/DATA/CONTAINER/HEADER/ATTRIBUTE[#name='lang']");
string SI = node.Attributes["value"].Value;
I don't how to extract the values from XML document, and am looking for some help as I'm new to C#
I am using XmlDocument and then XmlNodeList for fetching the particular XML document
Here is my code
XmlNodeList XMLList = doc.SelectNodes("/response/result/doc");
And my XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<result>
<doc>
<long name="LoadID">494</long>
<long name="EventID">5557</long>
<str name="XMLData"><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>tblQM2222Components</SubType><IntegerValue title="ComponentID">11111</IntegerValue></str></doc>
<doc>
<long name="LoadID">774</long>
<long name="EventID">5558</long>
<str name="XMLData"><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>tblQM2222Components</SubType><IntegerValue title="ComponentID">11111</IntegerValue></str></doc>
</result>
</response>
In this i have to fetch every the XMLData data that is under every doc tag and i have to fetch last doc tag EventID.
var xml = XDocument.Parse(xmlString);
var docs = xml.Root.Elements("doc");
var lastDocEventID = docs.Last()
.Elements("long")
.First(l => (string)l.Attribute("name") == "EventID")
.Value;
Console.WriteLine ("Last doc EventId: " +lastDocEventID);
foreach (var doc in docs)
{
Console.WriteLine (doc.Element("str").Element("TransactionDate").Value);
}
prints:
Last doc EventId: 5558
2014-05-28T14:17:31.2186777-06:00
2014-05-28T14:17:31.2186777-06:00
You can use two XPath expressions to select the nodes you want. To answer each part of your question in turn:
To select all of the XMLData nodes:
XmlNodeList XMLList
= doc.SelectNodes("/response/result/doc/str[#name='XMLData']");
To select the last EventId:
XmlNode lastEventIdNode =
doc.SelectSingleNode("/response/result/doc[position() =
last()]/long[#name='EventID']");
If not all doc nodes are guaranteed to have an event id child node, then you can simply:
XmlNodeList eventIdNodes =
doc.SelectNodes("/response/result/doc[long[#name='EventID']]");
XmlNode lastNode = eventIdNodes[eventIdNodes.Count - 1];
That should give you what you've asked for.
Update;
If you want the XML data inside each strXml element, you can use the InnerXml property:
XmlNodeList xmlList
= doc.SelectNodes("/response/result/doc/str[#name='XMLData']");
foreach(XmlNode xmlStrNode in xmlList)
{
string xmlInner = xmlStrNode.InnerXml;
}
There's one result tag short in your xml.
Try using this. It's cleaner too imho
XmlNodeList docs = doc.SelectSingleNode("response").SelectSingleNode("result").SelectNodes("doc");
Then you can use a combination of SelectSingleNode, InnerText, Value to get the data from each XmlNode in your list.
For example if you want the EventID from the first doc tag:
int eventID = int.Parse(docs[0].SelectSingleNode("long[#name='EventID']").InnerText);