This question already has answers here:
remove attribute if it exists from xmldocument
(2 answers)
Closed 4 years ago.
this is my XML
<root>
<CHILD ="1" UID="1">
<GrandChild>1</GrandChild>
</CHILD>
<CHILD ="2" UID="2">
<GrandChild>2</GrandChild>
</CHILD>
</root>
how can i remove child 1 from xml
Your xml is invalid because of the 'Child ="1"' syntax.
With valid xml you can parse using System.Xml.XmlDocument:
using System.Xml;
Create a new XmlDocument object:
XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object
If you are reading xml from a file, use xmlDoc.Load(string filename):
xmlDoc.Load("yourXMLFile.xml");
If you are reading xml from a string, use xmlDoc.LoadXml(string xml):
xmlDoc.LoadXml(xmlStringVariable);
From there, you can parse through your XML by the tag names and child nodes. Here is a simple example, but hopefully it will give you a start:
XmlNodeList childList = xmlDoc.GetElementsByTagName("CHILD");
var _child = childList[0];
for (int i = 0; i < childList.Count; i++)
{
// Do work
// Loop through child nodes
for(int c = 0; c < childList[i].ChildNodes.Count; c++)
{
// Do something with child nodes
var _childNode = childList[i].ChildNodes[c].InnerXml;
}
}
Related
This question already has answers here:
Check if XML Element exists
(13 answers)
C# Linq to XML check if element exists
(3 answers)
Closed 5 years ago.
I am trying to check if node "DEF" exists in my xml file
My xml file looks like this:
<Struct>
<A>
<ABC>
</ABC>
<DEF>
</DEF>
</A>
<B>
<GHI>
</GHI>
</B>
</Struct>
And my code looks like this:
XmlDocument stru = new XmlDocument();
stru.Load(path + "Structure.xml");
if (stru.ChildNodes[0].HasChildNodes)
{
for (int i = 0; i < stru.ChildNodes[0].ChildNodes.Count; i++)
{
if (stru.ChildNodes[0].ChildNodes[i].Attributes["DEF"] != null)
{
enabled = true;
break;
}
else
{
MessageBox.Show("no");
}
}
}
else { MessageBox.Show("Error!"); }
And it immediately shows messagebox with "Error!" in it
Use linq to xml with Descendants:
Returns a filtered collection of the descendant elements for this document or element, in document order. Only elements that have a matching XName are included in the collection.(Inherited from XContainer.)
var abcs = XDocument.Load("data.xml").Descendants("ABC");
if(abcs.Any())
{
// There is at least one element of "ABC"
}
This question already has answers here:
Deserializing XML from String
(2 answers)
Closed 6 years ago.
I get this XML string for my web page, how can I retrieve data from that XML and assign values to labels in my web page?
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<things>
<bat>201400000586</bat>
<status>Y</status>
<totalAmount>3090</totalAmount>
<billno>P2355</billno>
<ReceiveDate>27/04/2015 06:22:18 PM</ReceiveDate>
</things>
Firstly load the Xml Doc using XMLDocument
XDocument doc = XDocument.Load(filePath);
XElement rootElm = doc.Element("things")
Now using linq you can fetch IENumerable
IEnumerable<XElement> childList = from Y in rootElm.Root.Elements()
select Y;
Now ou can loop through list items
foreach (XElement elm in childList)
{
//Here you can access elements this way
Console.log(elm.Element("status").Value);
..........
}
Here you can even edit the contents in xml file and save them.
Assign the values for the XElement type elements in the loop
doc.Save(filePath);
There are different ways to do this. Here is one.
You'll need to add "using System.Xml.XPath;"
XPathDocument doc = new XPathDocument(Server.MapPath("~/XMLFile1.xml"));
XPathNavigator nav = doc.CreateNavigator();
XPathExpression exp = nav.Compile(#"/things");
foreach (XPathNavigator item in nav.Select(exp))
{
label1.Text = item.SelectSingleNode("bat").ToString();
label2.Text = item.SelectSingleNode("totalAmount").ToString();
}
Or you can load it as a string, then use EITHER XmlElement or XmlNode with such a simple XML structure.
XmlDocument m_xml = new XmlDocument();
m_xml.LoadXml(#"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes"" ?><things><bat>201400000586</bat><status>Y</status><totalAmount>3090</totalAmount><billno>P2355</billno><ReceiveDate>27/04/2015 06:22:18 PM</ReceiveDate></things>");
XmlNode node_bat = m_xml.SelectSingleNode("//things/bat");
XmlNode node_totalAmount = m_xml.SelectSingleNode("//things/totalAmount");
XmlElement node_bat1 = m_xml.DocumentElement["bat"];
XmlElement node_totalAmount1 = m_xml.DocumentElement["totalAmount"];
label1.Text = node_bat1.InnerText;
label2.Text = node_totalAmount1.InnerText;
This question already has answers here:
SelectSingleNode returns null when tag contains xmlNamespace
(4 answers)
Closed 7 years ago.
I am using SelectNodes to read xml nodes but i am getting null when i try GetElementsByTagName i get the values.
XmlDocument xml = new XmlDocument();
xml.Load(DownloadFile);
XmlNodeList xmlnode;
xmlnode = xml.GetElementsByTagName("CruisePriceSummaryResponse");
for (int i = 0; i < xmlnode.Count; i++)
{
XmlNodeList rooms = xml .SelectNodes("RoomSize/CruisePriceSummaryRoomSize");
for(int j = 0; j < rooms.Count; j++)
{
string bestFare = rooms[j].SelectSingleNode("BestFare/TotalPrice").InnerText;
string fullFare = rooms[j].SelectSingleNode("FullFare/TotalPrice").InnerText;
// do whatever you need
}
}
I want to read TotalPrice from BestFare and FullFare Each child has two innerchilds BestFare and FullFareand I need to read each TotalPrice.
This is my XML
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfCruisePriceSummaryResponse
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/OpenseasAPI.ServiceModel">
<CruisePriceSummaryResponse>
<AvailablePromos
xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d3p1:string>FLA</d3p1:string>
<d3p1:string>FLB</d3p1:string>
</AvailablePromos>
<Brand>PA</Brand>
<CruiseCategory i:nil="true"/>
<RoomSize>
<CruisePriceSummaryRoomSize>
<BestFare>
<TotalPrice>2798.0000000</TotalPrice>
</BestFare>
<FullFare>
<TotalPrice>3198.000000</TotalPrice>
</FullFare>
<PaxCount>2</PaxCount>
</CruisePriceSummaryRoomSize>
<CruisePriceSummaryRoomSize>
<BestFare>
<TotalPrice>2796.000000</TotalPrice>
</BestFare>
<FullFare>
<TotalPrice>4196.000000</TotalPrice>
</FullFare>
<PaxCount>4</PaxCount>
</CruisePriceSummaryRoomSize>
</RoomSize>
<ShipCode>PD</ShipCode>
</CruisePriceSummaryResponse>
<CruisePriceSummaryResponse>
<AvailablePromos
xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d3p1:string>FLA</d3p1:string>
<d3p1:string>LF1</d3p1:string>
</AvailablePromos>
<Brand>PA</Brand>
<RoomSize>
<CruisePriceSummaryRoomSize>
<BestFare>
<TotalPrice>1298.000000</TotalPrice>
</BestFare>
<FullFare>
<TotalPrice>3498.000000</TotalPrice>
</FullFare>
<PaxCount>2</PaxCount>
</CruisePriceSummaryRoomSize>
<CruisePriceSummaryRoomSize>
<BestFare>
<TotalPrice>1796.000000</TotalPrice>
</BestFare>
<FullFare>
<TotalPrice>5396.000000</TotalPrice>
</FullFare>
<PaxCount>4</PaxCount>
</CruisePriceSummaryRoomSize>
</RoomSize>
<ShipCode>PJ</ShipCode>
</CruisePriceSummaryResponse>
</ArrayOfCruisePriceSummaryResponse>
Help would be appreciated. I do not want to use linq as this is a SSIS project using VS2008 and it doesnot support linq.
Thanks in advance
You never load or read the source XML. Your code
XmlDocument xml = new XmlDocument();
XmlNodeList xmlnode;
xmlnode = xml.GetElementsByTagName("CruisePriceSummaryResponse");
creates an empty XML document, and then tries to get elements from the empty xml.
You need to call XmlDocument.Load or XmlDocument.LoadXML to read the xml from a file or a string.
XmlDocument xml = new XmlDocument();
xml.Load("pathtosomefile.xml");
XmlNodeList xmlnode = xml.GetElementsByTagName("CruisePriceSummaryResponse");
I am having a problem renaming child nodes in xml files using c#.
This is my xml file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<ZACAC01>
<IDOC BEGIN="1">
<ZACGPIAD SEGMENT="1">
<IDENTIFIER>D000</IDENTIFIER>
<CUST_DEL_NO/>
<CUST_DEL_DATE/>
<TRUCKNO/>
<DRIVERNAME/>
<DRIVERID/>
<RESPONS_OFF/>
<CONFIRM_DATE>20/01/13</CONFIRM_DATE>
<SERIAL_NO>2</SERIAL_NO>
<SERIAL_CHAR/>
<DEL_INFO1/>
<QTY>0</QTY>
<DEL_INFO2/>
<QTY>0</QTY>
<DEL_INFO3/>
<QTY>0</QTY>
<TRANS_COMPANY>0</TRANS_COMPANY>
</ZACGPIAD>
</IDOC>
</ZACAC01>
And below is my requirement:
<?xml version="1.0" encoding="ISO-8859-1"?>
<ZACAC01>
<IDOC BEGIN="1">
<ZACGPIADD SEGMENT="1">
<IDENTIFIER>D000</IDENTIFIER>
<CUST_DEL_NO/>
<CUST_DEL_DATE/>
<TRUCKNO/>
<DRIVERNAME/>
<DRIVERID/>
<RESPONS_OFF/>
<CONFIRM_DATE>20/01/13</CONFIRM_DATE>
<SERIAL_NO>2</SERIAL_NO>
<SERIAL_CHAR/>
<DEL_INFO1/>
<QTY1>0</QTY1>
<DEL_INFO2/>
<QTY2>0</QTY2>
<DEL_INFO3/>
<QTY3>0</QTY3>
<TRANS_COMPANY>0</TRANS_COMPANY>
</ZACGPIADD>
</IDOC>
</ZACAC01>
I am able to change the segment tag <ZACGPIAD> to this <ZACGPIADD> using the following code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(srcfile);
var root = xmlDoc.GetElementsByTagName("IDOC")[0];
var oldElem = root.SelectSingleNode("ZACGPIAD");
var newElem = xmlDoc.CreateElement("ZACGPIADD");
root.ReplaceChild(newElem, oldElem);
while (oldElem.ChildNodes.Count != 0)
{
newElem.AppendChild(oldElem.ChildNodes[0]);
}
while (oldElem.Attributes.Count != 0)
{
newElem.Attributes.Append(oldElem.Attributes[0]);
}
xmlDoc.Save(desfile);
But I can't change the <QTY> tag to <QTY1>, <QTY2>, <QTY3>
How can I do this?
I think you have the answer right in your code. You can use SelectSingleNode to pull the first <QTY> element with this:
var qtyNode = root.SelectSingleNode("ZACAC01/IDOC/ZACGPIADD/QTY[1]")
then use ReplaceChild on it's parent node. Then do the same for the second and third <QTY> nodes, replacing the '1' with '2' and '3' respectively.
You can use XDocument and operate on XElements which expose setter for node name (so you can simply set new name instead of doing node replacements):
var doc = XDocument.Load(srcfile);
var zacgpidNode = doc.Descendants("ZACGPIAD").First();
zacgpidNode.Name = "ZACGPIADD";
// now rename all QTY nodes
var qtyNodes = zacgpidNode.Elements("QTY").ToArray();
for (int i = 0; i < qtyNodes.Length; i++)
{
qtyNodes[i].Name = string.Format("{0}{1}", qtyNodes[i].Name, i+1);
}
doc.Save(desfile);
Having Descendants("ZACGPIAD").First() might not be suitable if your document structure is different than what you've shown in example. You can use XPathSelectElement method to have more control over what you'll be extracting:
var node = doc.XPathSelectElement("//IDOC[#BEGIN='1']/ZACGPIAD[#SEGMENT='1']");
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why XDocument can’t get element out of this wellform XML text?
I'm trying to read an xml using linq to xml, and i guess i'm understanding something wrong.
This is the start of the xml (it's long so i'm not posting it all)
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<Body>
<ReportItems>
<Tablix Name="Tablix12">
......
......
</Tablix>
This xml could have a few of "Tablix" elements, and might have 1 or none, for each one of these i want to read whats inside this tag and i'm having difficulty to start.
I have tried a few ways to get the "Tablix" elements, or any other element.
In this code i get a result only for the "var root", the rest of them are always null and i don't understand what i'm doing wrong.
public ReadTablixResponse ReadTablixAdvanced(string rdl)
{
XDocument xml = XDocument.Parse(rdl);
var root = xml.Root;
var Body = xml.Root.Element("Body");
var report = xml.Root.Element("Report");
var aa = xml.Element("Report");
var bb = xml.Element("Body");
var test = xml.Elements("Tablix");
One thing i noticed, is that you used the method Element("name"). which will always try to retrun the first (in document order) direct child element with the specified XName . and that is probebly why you got null.
if you want to return deeper elements(from where you looking). you need to use the Descendants("name") method, which will return a collection of all descendants elements . no matter how deep they are (relative to your chosen anchor)...
for example:
XNamespace xNameSpace = "http://schemas.micro.....";
// ...
var tablixes= xml.Descendants(xNameSpace + "Tablix");
which you can then wolk through:
foreach (var tablix in tablixes)
{
var name=(string)tablix.Attribute("Name");
var age=(int)tablix.Element("age");
...
}
XDocument xDocument = XDocument.Parse(rdl);
XNamespace xNameSpace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition";
var tablixes= from o in xDocument.Descendants(xNameSpace + "Tablix")
select o.Value;