I am trying to create an XML file using XmlDocument that will then be passed to an API. Most of the data outputs correctly however there is one element that does not, no matter what I try.
Here is my current output
<agentInventoryReference xmlns="demo.org.uk/demo/AgentInventoryReference"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<agentInventoryIdentity xmlns="">
<shed xmlns="demo.org.uk/demom/AgentInventoryIdentifier">TAX</shed>
<arrivalPort xmlns="demo.org.uk/demo/AgentInventoryIdentifier">LHR</arrivalPort>
<masterAirwayBillPrefix xmlns="demo.org.uk/demo/AgentInventoryIdentifier">125</masterAirwayBillPrefix>
<masterAirwayBillNumber xmlns="demo.org.uk/demo/AgentInventoryIdentifier">12345678</masterAirwayBillNumber>
<nominatedAgent xmlns="demo.org.uk/demo/AgentInventoryIdentifier">DRB</nominatedAgent>
</agentInventoryIdentity>
I need to drop the xmlns="" at the end of the opening agentInventoryIdentity element.
My code looks like this:
XmlDocument generateInventoryXml = new XmlDocument();
XmlElement root = generateInventoryXml.CreateElement ("agentInventoryReference", "demo.org.uk/demo/AgentInventoryReference");
root.SetAttribute("xmlns", "demo.org.uk/demo/AgentInventoryReference");
root.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
generateInventoryXml.AppendChild(root);
XmlElement agentInventoryIdentity = generateInventoryXml.CreateElement("agentInventoryIdentity");
XmlElement shed = generateInventoryXml.CreateElement("shed", "demo.org.uk/Sequoia/AgentInventoryIdentifier");
XmlElement arrivalport = generateInventoryXml.CreateElement("arrivalPort", "demo.org.uk/demo/AgentInventoryIdentifier");
XmlElement masterAirwayBillPrefix = generateInventoryXml.CreateElement("masterAirwayBillPrefix","demo.org.uk/demo/AgentInventoryIdentifier");
XmlElement masterAirwayBillNumber = generateInventoryXml.CreateElement("masterAirwayBillNumber", "demo.org.uk/demo/AgentInventoryIdentifier");
XmlElement nominatedAgent = generateInventoryXml.CreateElement("nominatedAgent", "demo.org.uk/demo/AgentInventoryIdentifier");
shed.InnerText = shedCode;
arrivalport.InnerText = arrivalPort;
masterAirwayBillPrefix.InnerText = awbPrefix;
masterAirwayBillNumber.InnerText = awbNumber;
nominatedAgent.InnerText = agent;
agentInventoryIdentity.AppendChild(shed);
agentInventoryIdentity.AppendChild(arrivalport);
agentInventoryIdentity.AppendChild(masterAirwayBillPrefix);
agentInventoryIdentity.AppendChild(masterAirwayBillNumber);
agentInventoryIdentity.AppendChild(nominatedAgent);
generateInventoryXml.DocumentElement.AppendChild(agentInventoryIdentity);
GenerateInventoryXml = generateInventoryXml.InnerXml;
Try this:
XmlElement agentInventoryIdentity = generateInventoryXml.CreateElement("agentInventoryIdentity",generateInventoryXml.DocumentElement.NamespaceURI);`
Or
XmlElement agentInventoryIdentity = generateInventoryXml.CreateElement("agentInventoryIdentity","demo.org.uk/demo/AgentInventoryReference");
Related
I'm getting this error when trying to append a node to existing element in my xml document.The error is: Object reference not set to an instance of an object.
<houses>
<house windowsc="three">
<wind>0</wind>
<windows>
</windows>
</house>
</houses>
Code:
XmlDocument xDoc = new XmlDocument();
xDoc.Load("C:\\Houseplans.xml");
XmlElement xhousing = xDoc.DocumentElement["houses/house[#windowsc=\"three\"]/windows"];
XmlNode xName = xDoc.CreateElement("Name");
xName.InnerText = "hi";
xhousing.AppendChild(xName);
You want to use SelectSingleNode:
XmlNode xhousing = xDoc.SelectSingleNode(#"//house[#windowsc='three']/windows");
XmlNode xName = xDoc.CreateElement("Name");
xName.InnerText = "hi";
xhousing.AppendChild(xName);
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;
So I have this XML:
<?xml version="1.0" encoding="utf-8"?>
<M_ChucVu>
<ChucVu>
<MaChucVu>1
</MaChucVu>
<TenChucVu>
</TenChucVu>
</ChucVu>
<ChucVu>
<MaChucVu>2
</MaChucVu>
<TenChucVu>
</TenChucVu>
</ChucVu>
<ChucVu>
<MaChucVu>23</MaChucVu>
<TenChucVu>12</TenChucVu>
</ChucVu>
<ChucVu>
<MaChucVu>44</MaChucVu>
<TenChucVu>44</TenChucVu>
</ChucVu>
</M_ChucVu>
and I want to retrieve the ChucVu tags that contain an empty TenChucVu tag so the result is this:
<ChucVu>
<MaChucVu>1
</MaChucVu>
<TenChucVu>
</TenChucVu>
</ChucVu>
<ChucVu>
<MaChucVu>2
</MaChucVu>
<TenChucVu>
</TenChucVu>
</ChucVu>
XDocument doc = ...;
var query = doc.XPathSelectElements("//ChucVu[TenChucVu='']");
Another XPath that should work
/M_ChucVu[./ChucVu/TenChucVu='']
for example
var doc = new XmlDocument();
doc.LoadXml(yourXmlString);
var elem = doc.DocumentElement;
var sel = elem.SelectNodes("/M_ChucVu[./ChucVu/TenChucVu!='']");
// print or use sel.InnerXml
The XPath you need is:
/*/ChucVu[not(string(TenChucVu))]
or
/*/ChucVu[string-length(TenChucVu)=0]
You can as:
string xparth = String.Format("//ChucVu[TenChucVu='{0}']", '');
XmlDocument doc = new XmlDocument();
doc.Load("Xml");
XmlElement root = doc.DocumentElement;
XmlNode node = root.SelectSingleNode(xparth);
XmlNodeList list = root.SelectNodes(xparth);
I'm looking for the simplest way to convert a string containing valid XML into an XmlElement object in C#.
How can you turn this into an XmlElement?
<item><name>wrench</name></item>
Use this:
private static XmlElement GetElement(string xml)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
return doc.DocumentElement;
}
Beware!!
If you need to add this element to another document first you need to Import it using ImportNode.
Suppose you already had a XmlDocument with children nodes, And you need add more child element from string.
XmlDocument xmlDoc = new XmlDocument();
// Add some child nodes manipulation in earlier
// ..
// Add more child nodes to existing XmlDocument from xml string
string strXml =
#"<item><name>wrench</name></item>
<item><name>screwdriver</name></item>";
XmlDocumentFragment xmlDocFragment = xmlDoc.CreateDocumentFragment();
xmlDocFragment.InnerXml = strXml;
xmlDoc.SelectSingleNode("root").AppendChild(xmlDocFragment);
The Result:
<root>
<item><name>this is earlier manipulation</name>
<item><name>wrench</name></item>
<item><name>screwdriver</name>
</root>
Use XmlDocument.LoadXml:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<item><name>wrench</name></item>");
XmlElement root = doc.DocumentElement;
(Or in case you're talking about XElement, use XDocument.Parse:)
XDocument doc = XDocument.Parse("<item><name>wrench</name></item>");
XElement root = doc.Root;
You can use XmlDocument.LoadXml() to do this.
Here is a simple examle:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("YOUR XML STRING");
I tried with this snippet, Got the solution.
// Sample string in the XML format
String s = "<Result> No Records found !<Result/>";
// Create the instance of XmlDocument
XmlDocument doc = new XmlDocument();
// Loads the XML from the string
doc.LoadXml(s);
// Returns the XMLElement of the loaded XML String
XmlElement xe = doc.DocumentElement;
// Print the xe
Console.out.println("Result :" + xe);
If any other better/ efficient way to implement the same, please let us know.
Thanks & Cheers
I have XML stored in string variable:
<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>
Here I want to change XML tag <ItemMasterList> to <Masterlist>. How can I do this?
System.Xml.XmlDocument and the associated classes in that same namespace will prove invaluable to you here.
XmlDocument doc = new XmlDocument();
doc.LoadXml(yourString);
XmlDocument docNew = new XmlDocument();
XmlElement newRoot = docNew.CreateElement("MasterList");
docNew.AppendChild(newRoot);
newRoot.InnerXml = doc.DocumentElement.InnerXml;
String xml = docNew.OuterXml;
I know i am a bit late, but just have to add this answer as no one seems to know about this.
XDocument doc = XDocument.Parse("<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>");
doc.Root.Name = "MasterList";
Which returns the following:
<MasterList>
<ItemMaster>
<fpartno>xxx</fpartno>
<frev>000</frev>
<fac>Default</fac>
</ItemMaster>
</MasterList>
You can use LINQ to XML to parse the XML string, create a new root and add the child elements and attributes of the original root to the new root:
XDocument doc = XDocument.Parse("<ItemMasterList>...</ItemMasterList>");
XDocument result = new XDocument(
new XElement("Masterlist", doc.Root.Attributes(), doc.Root.Nodes()));
Using the XmlDocument way, you can do this as follows (and keep the tree intact):
XmlDocument oldDoc = new XmlDocument();
oldDoc.LoadXml("<ItemMasterList><ItemMaster><fpartno>xxx</fpartno><frev>000</frev><fac>Default</fac></ItemMaster></ItemMasterList>");
XmlNode node = oldDoc.SelectSingleNode("ItemMasterList");
XmlDocument newDoc = new XmlDocument();
XmlElement ele = newDoc.CreateElement("MasterList");
ele.InnerXml = node.InnerXml;
If you now use ele.OuterXml is will return: (you you just need the string, otherwise use XmlDocument.AppendChild(ele) and you will be able to use the XmlDocument object some more)
<MasterList>
<ItemMaster>
<fpartno>xxx</fpartno>
<frev>000</frev>
<fac>Default</fac>
</ItemMaster>
</MasterList>
As pointed by Will A, we can do it that way but for case where InnerXml equals the OuterXml the following solution will work out:
// Create a new Xml doc object with root node as "NewRootNode" and
// copy the inner content from old doc object using the LastChild.
XmlDocument docNew = new XmlDocument();
XmlElement newRoot = docNew.CreateElement("NewRootNode");
docNew.AppendChild(newRoot);
// The below line solves the InnerXml equals the OuterXml Problem
newRoot.InnerXml = oldDoc.LastChild.InnerXml;
string xmlText = docNew.OuterXml;