Adding a namespace based element to an existing XML file - c#

How would I append <meta> element programatically to an existing XML file using XDocument
<Test xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:kishore="http://www.sample.com">
<meta>
<kishore:params kishore:version="1.0">
<kishore:textContent kishore:styleProp="TextProp" kishore:replaceID="Te"/>
</kishore:params>
</meta>
</Test>

Something like this should work:
var doc = new XDocument();
var root = new XElement(XName.Get("Test"));
var meta = new XElement(XName.Get("meta"));
root.Add(meta);
doc.Add(root);
Console.WriteLine(doc.ToString());

Related

How to Add a new element in XML document using c#

What I need is to add a new element to an XML Document that already exists. This is the XML:
And what I need is to add this element to the end of the element
<DATA>
<UBL21>true</UBL21>
<Partnership>
<ID>900430556</ID>
<TechKey>20c68c93ee595efaf227db3bc5d0e3416776bc487ec7058b9157c874eaa741a2</TechKey>
<SetTestID>dsfgsdghfsdgfsdfg</SetTestID>
</Partnership>
</DATA>
Expected result
This is the method with which I create the xml
public void guardar_nuevo_xml(InvoiceType df, string numero_factura)
{
//Here start xml df is an object from which I serialize the xml
XmlSerializer x = new XmlSerializer(df.GetType());
//path for save new document
string path = #"C:\Users\moralesm\source\repos\Pruebas_Nilo\Nilo\xml\Factura" + numero_factura + ".xml";
//write the new xml
TextWriter writer = new StreamWriter(path);
// the new xml is serialized with an object
x.Serialize(writer, df);
}
You can add element like this:
XDocument doc1 = XDocument.Load("Your Xml Path");
XElement dataElement = new XElement("DATA");
doc1.Root.Add(dataElement);
dataElement.Add(new XElement("UBL21", "true"));
XElement partnerShipElement = new XElement("Partnership");
dataElement.Add(partnerShipElement);
partnerShipElement.Add(new XElement("ID", "900430556"));
partnerShipElement.Add(new XElement("TechKey", "20c68c93ee595efaf227db3bc5d0e3416776bc487ec7058b9157c874eaa741a2"));
partnerShipElement.Add(new XElement("SetTestID", "dsfgsdghfsdgfsdfg"));
My Test Xml:
<test>
<name>Hidayet</name>
</test>
New Xml:
<test>
<name>Hidayet</name>
<DATA>
<UBL21>true</UBL21>
<Partnership>
<ID>900430556</ID>
<TechKey>20c68c93ee595efaf227db3bc5d0e3416776bc487ec7058b9157c874eaa741a2
</TechKey>
<SetTestID>dsfgsdghfsdgfsdfg</SetTestID>
</Partnership>
</DATA>
</test>
Save new xml file:
doc1.Save("New Xml File Path");

Unable to use InsertAfter for XmlDocument in c#

Hi below are the XML files which is master XML
<?xml version="1.0" encoding="utf-16"?>
<Verify>
<ver>
<ECU>
<values>
</values>
</ECU>
</ver>
</Verify>
I have multiple files which are of same structure as below
<?xml version="1.0" encoding="utf-16"?>
<Verify>
<ver>
<ECU>
<values>
</values>
</ECU>
</ver>
</Verify>
I want my output as
<?xml version="1.0" encoding="utf-16"?>
<Verify>
<ver>
<ECU>
<values>
</values>
</ECU>
<ECU>
<values>
</values>
</ECU>
<ECU>
<values>
</values>
</ECU>
</ver>
</Verify>
I am using below code to read first one as master xml
and other files from xmls folder. I want to add ECU node from these files under ECU node of master file.
XmlDocument xmlMaster = new XmlDocument();
xmlMaster.Load(#"C:\MasterXMLFile.xml");
XmlElement masterRoot = xmlMaster.DocumentElement;
XmlNode masterParent = masterRoot.LastChild.LastChild;
var downloadfolder = #"C:\AllXMLs\xmls\";
string[] files = Directory.GetFiles(downloadfolder);
foreach (var xx in files)
{
XmlNode masterNode = masterRoot.LastChild.LastChild;
XmlDocument xdoc = new XmlDocument();
xdoc.Load(xx);
XmlElement root = xdoc.DocumentElement;
XmlElement tempNode = (XmlElement)root.LastChild.LastChild;
masterRoot.InsertAfter(tempNode, masterRoot.SelectSingleNode("//ECU").ParentNode);
}
xmlMaster.Save(#"C:\mergeg.xml");
I am getting error at InsertAfter statement as Object reference not set to an instance of an object.
Please suggest me any solution.
Your tempNode is from xdoc document context. You should import it to xmlMaster document context:
XmlNode importedECU = xmlMaster.ImportNode(tempNode, true);
Also instead of InsertAfter it's better to use AppendChild and append new ECU nodes as children of master ver element:
var masterVer = masterRoot.SelectSingleNode("//ver");
foreach(var file in files)
{
var xdoc = new XmlDocument();
xdoc.Load(file);
var tempNode = xdoc.DocumentElement.LastChild.LastChild;
var importedECU = xmlMaster.ImportNode(tempNode, true);
masterVer.AppendChild(importedECU);
}
Your InsertAfter should be on the parentNode of the node you want to insert after, so the parent of tempNode.

How to write xsd:schema tag using XmlDocument

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>

Trying to change a XML node with no success

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

C# remove attribute from root node

I tries to parse a XML file (get it from Dependacy Graph in VS 2012).
Here is sample of my .xml file
<?xml version="1.0" encoding="utf-8"?>
<DirectedGraph xmlns="http://schemas.microsoft.com/vs/2009/dgml">
<Nodes>
<Node Id="#101" Category="CodeSchema_ProjectItem" FilePath="$(ProgramFiles)\windows kits\8.0\include\um\unknwnbase.h" Label="unknwnbase.h" />
<Node Id="#103" Category="CodeSchema_ProjectItem" FilePath="$(ProgramFiles)\windows kits\8.0\include\shared\wtypesbase.h" Label="wtypesbase.h" />
in here, I needs to remove attribute "xmlns" from DirectedGraph.
here's my source to remove this
XmlNodeList rootNode = xmlDoc.GetElementsByTagName("DirectedGraph");
foreach (XmlNode node in rootNode)
{
node.Attributes.RemoveNamedItem("xmlns");
}
but this code doesn't work. If I don't delete this I can't select node like
XmlNodeList nodes = xmlDoc.DocumentElement.SelectNodes("/DirectedGraph/Nodes/Node");
What should I do?
If you like you can work with the namespace instead of removing the declaration:
var xml = #"<?xml version=""1.0"" encoding=""utf-8""?>
<DirectedGraph xmlns=""http://schemas.microsoft.com/vs/2009/dgml"">
<Nodes>
<Node Id=""#101"" Category=""CodeSchema_ProjectItem"" FilePath=""$(ProgramFiles)\windows kits\8.0\include\um\unknwnbase.h"" Label=""unknwnbase.h"" />
<Node Id=""#103"" Category=""CodeSchema_ProjectItem"" FilePath=""$(ProgramFiles)\windows kits\8.0\include\shared\wtypesbase.h"" Label=""wtypesbase.h"" />
</Nodes>
</DirectedGraph>";
var doc = new XmlDocument();
doc.LoadXml(xml);
var manager = new XmlNamespaceManager(doc.NameTable);
manager.AddNamespace("d", "http://schemas.microsoft.com/vs/2009/dgml");
var nodes = doc.DocumentElement.SelectNodes("/d:DirectedGraph/d:Nodes/d:Node", manager);
Console.WriteLine(nodes.Count);
Use:
private static XElement RemoveAllNamespaces(XElement xmlDocument)
{
if (!xmlDocument.HasElements)
{
XElement xElement = new XElement(xmlDocument.Name.LocalName);
xElement.Value = xmlDocument.Value;
foreach (XAttribute attribute in xmlDocument.Attributes())
xElement.Add(attribute);
return xElement;
}
return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
}
Taken from: How to remove all namespaces from XML with C#?.
You might also want to check out: XmlSerializer: remove unnecessary xsi and xsd namespaces.

Categories

Resources