Amending an XML file - c#

I have been trying over the past day to read and amend this xml
<TimeSeriesDocument xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:Test">
<DocumentIdentification v="ZDAE_02417b6a-477a-a-4aa19e1c4712"/>
<TimeSeries>
<Period>
<TimeInterval v="12" />
<Resolution v="PT1H" />
<Interval>
<Pos v="17" />
<Qty v="0" />
</Interval>
<Interval>
<Pos v="19" />
<Qty v="10" />
</Interval>
</Period>
</TimeSeries>
</TimeSeriesDocument>
I want to amend each Qty within each Interval within the period
I have been using Descendants but i'm struggling to loop over each Interval and pick and change the Qty
var doc = XDocument.Load(test.xml);
var periods = doc.Descendants("TimeSeriesDocument/TimeSeries").Select(e => new { name = e.Element("Period").Value });
Can you please help?

A sample console application to loop through Qty nodes and set new value for v attribute:
class Program
{
static void Main(string[] args)
{
var document = new XmlDocument();
document.Load("Sample.xml");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
nsmgr.AddNamespace("ns", "urn:Test");
var intervalNodes = document.SelectNodes("//ns:Interval", nsmgr);
foreach(XmlNode node in intervalNodes)
{
var quantityNode = node.SelectSingleNode("./ns:Qty", nsmgr);
quantityNode.Attributes["v"].Value = "New Value";
}
}
}

XNamespace ns = "urn:Test";
XElement doc = XElement.Load("file.xml");
var periods = doc.Descendants(ns + "Period");
var intervals = periods.Elements(ns + "Interval");
foreach (var qty in intervals.Elements(ns + "Qty"))
{
qty.Attribute("v").Value = "42";
}

Related

XDocument just reads the first title?

I need to parse xml but my code just parses one title not all.
How can I parse part ?
This is my code:
CustomResponse itemCustom = new CustomResponse ();
XDocument response = XDocument.Parse(responseXml);
XElement rootElement = response.Root;
foreach (XElement sellResponse in rootElement.Elements())
{
itemCustom .ErrorCode = sellResponse.Element("ErrorCode").Value;
itemCustom .ErrorMessage = sellResponse.Element("ErrorMessage").Value;
itemCustom .CustomerID= sellResponse.Element("CustomerID").Value;
itemCustom .CustomerType= sellResponse.Element("CustomerType").Value;
}
This is my xml:
<?xml version="1.0" encoding="utf-8"?>
<TINS_XML_DATA>
<Header>
<ErrorCode>WAATS</ErrorCode>
<ErrorMessage>UTL</ErrorMessage>
</Header>
<Customer>
<CustomerID>UTL11111111111111111111</CustomerID>
<CustomerType>NSell</CustomerType>
</Customer>
</TINS_XML_DATA>
Try something like this:
foreach (XElement sellResponse in rootElement.Elements())
{
if (sellResponse.Name == "Header")
{
itemCustom.ErrorCode = sellResponse.Element("ErrorCode").Value;
itemCustom.ErrorMessage = sellResponse.Element("ErrorMessage").Value;
}
else if (sellResponse.Name == "Customer")
{
itemCustom.CustomerID = sellResponse.Element("CustomerID").Value;
itemCustom.CustomerType = sellResponse.Element("CustomerType").Value;
}
}
Update: You could also use XPath to find required elements as like below:
var xDoc = new XmlDocument();
xDoc.LoadXml(xml);
var errorMessage = xDoc.SelectNodes("//ErrorMessage")[0].InnerText;
This is my solved:
var xDoc = new XmlDocument();
xDoc.LoadXml(responseXml);
itemSell.ErrorCode = xDoc.SelectNodes("//ErrorCode")[0].InnerText;
itemSell.ErrorMessage = xDoc.SelectNodes("//ErrorMessage")[0].InnerText;
itemSell.CustomerID= xDoc.SelectNodes("//CustomerID")[0].InnerText;

XmlDocument.SelectSingleNode

I have a soap xml message and need to fetch a single node value from given soap xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://tews6/wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Body>
<testResult>
<Status version="6.0" >
<NNO>277982b4-2917a65f-13ffb8c0-b09751f</NNO>
</Status>
<ProfileTab>
<Email>abc#gmail.com</Email>
<Name>abc</Name>
</Profile>
</testResult></soapenv:Body></soapenv:Envelope>
I need to fetch the value of Email node. I used the below code
rootNode = "soapenv:Envelope/soapenv:Body/ProfileTab/Email";
var nsmgr = new XmlNamespaceManager(document.NameTable);
nsmgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
node = document.SelectSingleNode(rootNode,nsmgr);
It is returning the null.
You can use the following.
var rootNode = "soapenv:Envelope/soapenv:Body/tews6:testResult/tews6:ProfileTab/tews6:Email";
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("tews6", "http://tews6/wsdl");
nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
var node = doc.SelectSingleNode(rootNode, nsmgr);
Try this:
string xml="xml";
XDocument doc = XDocument.Parse(xml);
XNamespace bodyNameSpace ="http://schemas.xmlsoap.org/soap/envelope/";
var bodyXml = from _e in doc.Descendants(bodyNameSpace + "Body")
select _e;
if (bodyXml.Elements().Count() == 0)
{
return;
}
var email = from _e in bodyXml.First()Descendants("Email")
select _e;
if(email.Count()==1)
{
string emailAddress=email.First().Value;
}

Add attributes using XAttribute

I have a root XML which is like this:
<Root xmlns="http://schemas.datacontract.org/2004/07/" xmlns:t="http://www.w3.org/2001/XMLSchema-instance">
<Element1>somevalue</Element1>
<Data/>
<Root>
I need to add few customer related informaiton like (Name, Age etc) under Data Element Node. So, the result I expect is follows:
<Root xmlns="http://schemas.datacontract.org/2004/07/" xmlns:t="http://www.w3.org/2001/XMLSchema-instance">
<Element1>somevalue</Element1>
<Data>
<Name t:type="xs:string" xmlns="" xmlns:s="http://www.w3.org/2001/XMLSchema">Elvis</Name>
<Address t:type="xs:string" xmlns="" xmlns:s="http://www.w3.org/2001/XMLSchema">Some address</Address>
</Data>
<Root>
How can I achieve this? I am using C#, .net 4.0.
I was trying out the below code, but didn't get the result I was expecting:
string strTemplate = "<Root xmlns='http://schemas.datacontract.org/2004/07/' xmlns:t='http://www.w3.org/2001/XMLSchema-instance'><Element1>somevalue</Element1><Data/></Root>";
XDocument doc = XDocument.Parse(strTemplate);
XElement rootElement = doc.Root;
XElement dataElement = null;
foreach (XElement descendant in rootElement.Descendants())
{
if (descendant.Name.LocalName == "Data")
{
dataElement = descendant;
break;
}
}
string cusData = "<CustData><Name>Elvis</Name><Address>XYZ</Address></CustData>";
XElement customerElements = XElement.Parse(cusData);
if (dataElement != null)
{
foreach (XElement custAttributes in customerElements.Descendants())
{
XNamespace t = "http://www.w3.org/2001/XMLSchema-instance";
var attribute = new XAttribute(t + "type", "xs:string");
var attribute1 = new XAttribute(XNamespace.Xmlns + "s", "http://www.w3.org/2001/XMLSchema");
XElement element = new XElement(custAttributes.Name, attribute, attribute1);
element.Value = custAttributes.Value;
dataElement.Add(element);
}
}
string strPayload = doc.ToString();
When I execute the code I get the following:
<Data xmlns="http://schemas.datacontract.org/2004/07/">
<Name t:type="xs:string" xmlns:t="http://www.w3.org/2001/XMLSchema-instance" xmlns="">Elvis</Name>
<Address t:type="xs:string" xmlns:t="http://www.w3.org/2001/XMLSchema-instance" xmlns="">XYZ</Address>
</Data>
Any help appreciated!
Thanks,
M

How I get the parentnode attribute name if I have the attribute name of the child node?

hi i want to get the up node from a xml. For example here a xml structure...
<feature name="mod1">
<user name="user1"></user>
<user name="user2"></user>
<user name="user3"></user>
</feature>
i have in my application the username and i want than the node feature name attribute.
XmlReader reader = XmlReader.Create(new StringReader(xml));
XElement doc = XElement.Load(reader);
int counter = 0;
foreach (XElement user in doc.Descendants("USER"))
{
try
{
row = tb.NewRow();
row["ID"] = counter++;
row["Name"] = user.Attribute("NAME").Value;
row["Host"] = user.Attribute("HOST").Value;
row["Used_Licenses"] = user.Attribute("USED_LICENSES").Value;
row["Checkout_Time"] = user.Attribute("CHECKOUT_TIME").Value;
row["Modul"] = user.Parent.Attribute("NAME").Value; //don't work :(
tb.Rows.Add(row);
}
catch (Exception)
{
}
}
you should be able to get it by
user.Parent.Attribute("NAME").Value;
this Works with :
<LM-X STAT_VERSION="3.32">
<LICENSE_PATH >
<FEATURE NAME="GlobalZoneEU" >
<USER NAME="SYSTEM" HOST="LRV171" IP="172.16.11.115" USED_LICENSES="2000" LOGIN_TIME="2013-04-17 12:42" CHECKOUT_TIME="2013-04-17 12:42" SHARE_CUSTOM="hweuser:172.16.11.115"/>
<USER NAME="pbsadmin" HOST="SERV11" IP="172.16.11.115" USED_LICENSES="720" LOGIN_TIME="2013-04-17 12:44" CHECKOUT_TIME="2013-04-17 12:44" SHARE_CUSTOM="pbsadmin:LWSERV171:1592_40960072_1356792762_826820"/>
</FEATURE>
</LICENSE_PATH>
</LM-X>
EDIT
Get the feature name by user name :
var featureNames = xDoc.Descendants("USER")
.Where(x => x.Attribute("NAME").Value == <your input>)
.Select(x => x.Parent.Attribute("NAME").Value);
var firstFeatureName = featureNames.FirstOrDefault();
Seems like the attributes are case sensitive.
XmlReader reader = XmlReader.Create(\\File Path);
XElement doc = XElement.Load(reader);
int counter = 0;
foreach (XElement user in doc.Descendants("USER"))
{
try
{
string node = user.Parent.Attribute("NAME").Value; //Working - Returning 'GlobalZoneEU'
}
catch (Exception)
{
}
}
The following code should work for you.
string xml = "<feature name=\"mod1\">";
xml += "<user name=\"user1\"> </user>";
xml += "<user name=\"user2\"> </user> ";
xml += "<user name=\"user3\"></user>";
xml += "</feature>";
XmlDocument xdoc=new XmlDocument();
xdoc.LoadXml(xml);
XDocument mydoc = XDocument.Parse(xdoc.OuterXml);
var result = mydoc.Elements("feature").Where(parent =>
parent.Elements("user").Any(child =>
child.Attribute("name").Value == "user2"));
and don't forget to include
using System.Xml;
using System.Xml.Linq;

how to determine count of tag

I have a bit of xml file named Sample.xml which is shown below
<?xml version="1.0" encoding="ISO-8859-1"?>
<countries>
<country>
<text>Norway</text>
<value>N</value>
</country>
<country>
<text>Sweden</text>
<value>S</value>
</country>
<country>
<text>France</text>
<value>F</value>
</country>
<country>
<text>Italy</text>
<value>I</value>
</country>
</countries>
i have button named submit(button1).If i click that button i need to display the count(PartitionName="AIX") in a text box named textBox1, means How many PartitionName="AIX" is belonging to Type="NIC"
Can any one give me the c# code
I did like this,,but not able to get the answaer
private void button1_Click(object sender, EventArgs e)
{
XmlDocument doc1 = new XmlDocument();
doc1.Load(#"D:\New Folder\WindowsFormsApplication3\WindowsFormsApplication3\Sample.xml");
XmlNodeList a = doc1.GetElementsByTagName("AIX");
textBox1.Text = a.Count.ToString();
}
here is a quick soln I arrived at using linq. hope you find it useful.
static void Main(string[] args)
{
XElement xElement = XElement.Load(#"C:\Labs\test.xml");
// PartitionName="AIX" is belonging to Type="NIC"
var count = xElement.Descendants().Where(x => x.Name.ToString().Contains("Port")) // namespaces might be used here for faster traversal..
.Where(x => x.HasAttributes && x.Attribute("Type").Value == "NIC")
.Descendants().Where(x => x.Name.ToString().Contains("Client"))
.Where(x => x.Attribute("PartitionName").Value == "AIX").Count();
string str = count.ToString();
Console.WriteLine("Count = {0}", str);
Console.ReadLine();
}
Using xpath something like this:
count(vendor/Slot/Port[#Type='NIC']/Client[#PartitionName='AIX'])
But you have to modify it to support your namespaces.
Also easier and shorter code than going the Linq route for this particular case.
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("inv", "http://secon.com/Ultravendor");
int count = doc.SelectNodes("inv:vendor/inv:Slot/inv:Port[#Type='NIC']/inv:Client[#PartitionName='AIX']", nsMgr).Count;
XmlDocument doc1 = new XmlDocument();
doc1.Load(#"C:\Labs\test.xml");
XmlNodeList nodes = doc1.GetElementsByTagName("inv:Port");
int count = 0;
foreach (XmlNode childNode in nodes)
{
XmlNodeReader nodeReader = new XmlNodeReader(childNode);
while (nodeReader.Read())
{
if (nodeReader.GetAttribute("PartitionName") == "AIX")
{
count++;
}
}
}
Console.WriteLine("Count = {0}", count);
Console.ReadLine();

Categories

Resources