Add attributes using XAttribute - c#

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

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;

Why is XPathNodeIterator not finding desired path?

I am having a problem with XPathNodeIterator grabbing the data from the given path. When debugging, pNav has all the values from the xml file. However iterator shows a count of 0. It never enters the while loop. Any help would be appreciated.
C#
XPathDocument pdoc = new XPathDocument("Courses.xml");
XPathNavigator pNav = pdoc.CreateNavigator();
XPathNodeIterator iterator = pNav.Select("/Courses/Course");
while (iterator.MoveNext())
{
XPathNodeIterator it = iterator.Current.Select("Name");
it.MoveNext();
string courseName = it.Current.Value;
it = iterator.Current.Select("Code");
it.MoveNext();
string courseCode = it.Current.Value;
Console.WriteLine("{0} {1}", courseName, courseCode);
}
XML:
<Courses xmlns="http://xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="Courses.xsd">
<Course>
<Code Undergrad="240"/>
<Name>Biology</Name>
<Instructor>
<Name>
<First>John</First>
<Last>Doe</Last>
</Name>
<Contact>
<Phone>898-989-8989</Phone>
</Contact>
</Instructor>
<Room>515</Room>
</Course>
</Courses>
I expect the output to be
Name = Biology, Code = 240
Because you have
xmlns="http://xml"
in your XML file you need to add a XmlNamespaceManager to allow the navigator to find the nodes. If you remove the xmlns="http://xml" from your XML then you won't need to use an XmlNamespaceManager.
Also the Select method returns a collection of nodes - you need to call SelectSingleNode to get the node you want. E.G.
XPathDocument pdoc = new XPathDocument("Courses.xml");
XPathNavigator pNav = pdoc.CreateNavigator();
var manager = new XmlNamespaceManager(pNav.NameTable);
manager.AddNamespace("cs", "http://xml");
XPathNodeIterator iterator = pNav.Select("/cs:Courses/cs:Course", manager);
while(iterator.MoveNext())
{
var nameNode = iterator.Current.SelectSingleNode("cs:Name", manager);
string courseName = nameNode.Value;
var codeNode = iterator.Current.SelectSingleNode("cs:Code", manager);
codeNode.MoveToFirstAttribute();
string courseCode = codeNode.Value;
Console.WriteLine("{0} {1}", courseName, courseCode);
}
When you get to the Code element, you need to move to the first attribute to get the value, otherwise Value property will return an empty string
It needs to pass namespace resolver to Select-method:
const string xml = #"
<Courses xmlns=""http://xml"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:schemaLocation=""Courses.xsd"">
<Course>
<Code Undergrad=""240""/>
<Name>Biology</Name>
<Instructor>
<Name>
<First>John</First>
<Last>Doe</Last>
</Name>
<Contact>
<Phone>898-989-8989</Phone>
</Contact>
</Instructor>
<Room>515</Room>
</Course>
<Course>
<Code Undergrad=""000""/>
<Name>Math</Name>
<Instructor>
<Name>
<First>John</First>
<Last>Doe</Last>
</Name>
<Contact>
<Phone>898-989-8989</Phone>
</Contact>
</Instructor>
<Room>515</Room>
</Course>
</Courses>";
using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(xml)))
{
var pdoc = new XPathDocument(stream);
var pNav = pdoc.CreateNavigator();
var manager = new XmlNamespaceManager(pNav.NameTable);
manager.AddNamespace("cs", "http://xml");
var iterator = pNav.Select("/cs:Courses/cs:Course", manager);
foreach (XPathNavigator node in iterator)
{
var courseName = node.SelectSingleNode("cs:Name", manager)?.Value;
var courseCode = node.SelectSingleNode("cs:Code", manager)?.GetAttribute("Undergrad", string.Empty);
Console.WriteLine("{0} {1}", courseName, courseCode);
}
}

How to add XNamespace to XDocument's root element?

I'm generating Xml Documemnt via Linq To Xml. It is added 'xmlns' attribute to all elements with empty values.
How to remove unwanted attributes?
XNamespace np = "example";
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", string.Empty),
new XElement(np + "root")
);
var list = new List<string> { "1", "2", "3" };
foreach (var item in list)
{
var xE = new XElement("child",
new XElement("first", item),
new XElement("second", item)
);
doc.Root.AddFirst(xE);
}
I expect the result.
Only xmlns attribute in root element
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="example">
<child>
<first>3</first>
<second>3</second>
</child>
<child >
<first>2</first>
<second>2</second>
</child>
<child>
<first>1</first>
<second>1</second>
</child>
</root>
But getting
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="example">
<child xmlns=""> //unwanted attribute
<first>3</first>
<second>3</second>
</child>
<child xmlns="">
<first>2</first>
<second>2</second>
</child>
<child xmlns="">
<first>1</first>
<second>1</second>
</child>
</root
It needs to add XNamespace to every XElement.
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", string.Empty),
new XElement(np + "root")
);
var list = new List<string> { "1", "2", "3" };
foreach (var item in list)
{
var xE = new XElement(np+"child",
new XElement(np+"first", item),
new XElement(np+"second", item)
);
doc.Root.AddFirst(xE);
}

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

Reading value from XML

I am new to C# asp.net coding so I am facing a bit problem.
This is my xml file. I want to retrieve " < DOB > " values of each employee and want to store them in a list, say "emps_dob". Please help me with this. Thank u
<?xml version="1.0" encoding="utf-8"?>
<employees>
<employee>
<name> Vin </name>
<DOB> 07/10 </DOB>
<emailID> vinay#abc.com</emailID>
</employee>
<employee>
<name> ben </name>
<DOB> 08/11 </DOB>
<emailID> ben#abc.com</emailID>
</employee>
<employee>
<name> tin </name>
<DOB> 09/12 </DOB>
<emailID> tin#abc.com</emailID>
</employee>
You can use linq as per answer given in this post
var doc = XDocument.Load("yourfilepath")
var dobs= doc.Root.Elements().Select( x => x.Element("DOB") );
OR
using System;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main( string[] args )
{
XDocument doc = XDocument.Load( "XMLFile1.xml" );
List<string> emps_dob=new List<string>();
var dobs= doc.Descendants( "DOB" );
foreach ( var item in dobs)
{
emps_dob.Add(item.Value);
}
}
}
}
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString);
XmlNodeList xnList = xml.SelectNodes("/employees/employee");
foreach (XmlNode xn in xnList)
{
string name= xn["name"].InnerText;
string DOB= xn["name"].InnerText;
Console.WriteLine("Name: {0} {1}", name, DOB);
}
using System.Xml;
List<string> dob = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load("abc.xml");
XmlNode root = doc.DocumentElement;
foreach (XmlNode node1 in root.ChildNodes)
{
foreach (XmlNode node2 in node1.ChildNodes)
{
if (node2.Name.ToString() == "DOB")
dob.Add(node2.InnerText.ToString());
}
}

Categories

Resources