How to get xml element values to a string using Xdocument - c#

I am storing a xml in a string and using Xdocument i am parsing the string to xml from that i need to get xml element values and using that values i need to insert it in db. Any help would be appreciated.
XML:
<ListInventorySupplyResponse xmlns="http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/">
- <ListInventorySupplyResult>
- <InventorySupplyList>
- <member>
<SellerSKU>043859634910</SellerSKU>
<FNSKU>X000IA4045</FNSKU>
<ASIN>B005YV4DJO</ASIN>
<Condition>NewItem</Condition>
<TotalSupplyQuantity>10</TotalSupplyQuantity>
<InStockSupplyQuantity>10</InStockSupplyQuantity>
- <EarliestAvailability>
<TimepointType>Immediately</TimepointType>
</EarliestAvailability>
<SupplyDetail />
</member>
</InventorySupplyList>
</ListInventorySupplyResult>
- <ResponseMetadata>
<RequestId>d50af29d-f203-4efc-a864-1725a59ded97</RequestId>
</ResponseMetadata>
</ListInventorySupplyResponse>
Code:
XDocument xd = XDocument.Parse(a);
string Sku = xd.Element();
var ASIN = xd.Descendants("ASIN");
var Condition = xd.Descendants("Condition");
var TotalSupplyQuantity = xd.Descendants("TotalSupplyQuantity");

You should use the xml namespace http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/
var xDoc = XDocument.Parse(xml);
XNamespace ns = "http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/";
var condition = (string)xDoc.Descendants(ns + "Condition").First();
OR
you can search for Tag Condition in any xml namespace
var condition2 = (string)xDoc.Descendants()
.First(d => d.Name.LocalName == "Condition");
OR
you can use XPath to get Condition in any xml namespace
var condition3 = (string)xDoc.XPathSelectElement("//*[local-name()='Condition']");

Use this:
string value = xd.Root.Element("SellerSKU").Value;

Related

C# XML querying using XPath containing a namespace

In C# I'm struggling to understand how to query XML using XPath that includes a namespace.
XML:
<?xml version="1.0" encoding="utf-8"?>
<SomeEntity xmlns="http://www.example.com/Schemas/SomeEntity/2023/01">
<Child>
<TextValue>Some text</TextValue>
</Child>
</SomeEntity>
XPath:
/SomeEntity[#xmlns="http://www.example.com/Schemas/SomeEntity/2023/01"]/Child/TextValue
C#:
XmlNodeList nodes = doc.SelectNodes(xpath); \\ doc being of type XmlDocument
SelectNodes always results in an empty XmlNodeList.
What's the best way in C# to resolve XPath queries that include a namespace in this way?
I get the same result when using XDocument:
var doc = XDocument.Parse(xml);
string xpath = #"/SomeEntity[#xmlns=""http://www.example.com/Schemas/SomeEntity/2023/01""]/Child/TextValue";
var results = doc.XPathSelectElements(xpath);
It is better to use LINQ to XML.
There is no need to hardcode the default namespace. The GetDefaultNamespace() call gets it for you.
c#
void Main()
{
XDocument xdoc = XDocument.Parse(#"<SomeEntity xmlns='http://www.example.com/Schemas/SomeEntity/2023/01'>
<Child>
<TextValue>Some text</TextValue>
</Child>
</SomeEntity>");
XNamespace ns = xdoc.Root.GetDefaultNamespace();
string TextValue = xdoc.Descendants(ns + "TextValue")?.FirstOrDefault().Value;
Console.WriteLine("TextValue='{0}'", TextValue);
}
Output
TextValue='Some text'
For querying with the xmlns attibute condition, with #xmlns is not working. Instead, you need namespace-uri().
Pre-requisites:
Must add the XML namespace for query.
Provide the namespace prefix in the query.
For XmlDocument
string xpath = #"//se:SomeEntity[namespace-uri()='http://www.example.com/Schemas/SomeEntity/2023/01']/se:Child/se:TextValue";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("se", "http://www.example.com/Schemas/SomeEntity/2023/01");
var nodes = doc.DocumentElement.SelectNodes(xpath, mgr);
Console.WriteLine(nodes.Count);
Console.WriteLine(nodes.Item(0).FirstChild.Value);
For XDocument
using System.Linq;
using System.Xml.XPath;
using System.Xml.Linq;
string xpath = #"//se:SomeEntity[namespace-uri()='http://www.example.com/Schemas/SomeEntity/2023/01']/se:Child/se:TextValue";
var xDoc = XDocument.Parse(xml);
var mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("se", "http://www.example.com/Schemas/SomeEntity/2023/01");
var results = xDoc.XPathSelectElements(xpath, mgr);
Console.WriteLine(results.FirstOrDefault()?.Value);

Update XML file with C#

I have a xml file:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationConfiguration xmlns="http://test.org/SDK/Configuration.xsd">
<ApplicationName>
<ApplicationUri>123</ApplicationUri>
<ApplicationUri>456</ApplicationUri>
</ApplicationName>
</ApplicationConfiguration>
What I want is set the value of ApplicationUri from 456 to 789 in C# code.
I wrote this code:
string docaddress = "testfile.xml";
XDocument doc = XDocument.Load(docaddress);
doc.Element("ApplicationConfiguration")
.Elements("ApplicationName").FirstOrDefault()
.SetElementValue("ApplicationUri", "789");
doc.Save(docaddress);
The problems are:
There is no error while running. I think the element ApplicationConfiguration is not correct. But when I delete the line xmlns=... from the xml file, it runs normally
The value 789 is replaced with 123, but not 456 as I want (same element name)
Can you tell me how to fix those problems?
Hello and welcome to Stack Overflow!
The xmlns attribute on the ApplicationConfiguration element makes that the root.
So you get the root first. Then you replace the values of each descendant, selecting locally by name with the element name you want. something like this:
string docaddress = "C:\\temp\\testfile.xml";
XDocument doc = XDocument.Load(docaddress);
var root = doc.Root;
var descendants = root.Descendants();
var these = root.Descendants().Where(p => p.Name.LocalName == "ApplicationUri");
foreach (var elem in these)
{
elem.Value = "789";
}
doc.Save(docaddress);
I added namespace to your code :
string docaddress = "testfile.xml";
XDocument doc = XDocument.Load(docaddress);
XNamespace ns = doc.Root.GetDefaultNamespace();
doc.Element(ns + "ApplicationConfiguration")
.Elements(ns + "ApplicationName").FirstOrDefault()
.SetElementValue(ns + "ApplicationUri", "789");
doc.Save(docaddress);
IMHO, here is an easiest method.
It is taking care of the XML default namespace.
No loops. Set based approach.
c#
void Main()
{
const string fileName = #"e:\temp\hala.xml";
const string searchFor = "456";
const string replaceWith = "789";
XDocument doc = XDocument.Load(fileName);
XNamespace ns = doc.Root.GetDefaultNamespace();
// step #1: find element based on the search value
XElement xmlFragment = doc.Descendants(ns + "ApplicationUri")
.Where(d => d.Value.Equals(searchFor)).FirstOrDefault();
// step #2: if found, set its value
if(xmlFragment != null)
xmlFragment.SetValue(replaceWith);
doc.Save(fileName);
}

Get node property of XmlDocument in C#

I'm using this xml structure:
<park>
<car title="Ferrari" available="true">
<url>http://www.ferrari.com/</url>
</rss>
</park>
And this is my code in C#:
XmlDocument doc = new XmlDocument();
doc.Load("Settings.xml");
XmlNodeList list = doc.SelectNodes("/park/car");
foreach (XmlNode item in list)
{
string x = item["#title"].InnerText;
}
I just want to get "title" property but i can't get it working. I'm using "#" but without success.
Try this code:
string x = item.Attributes["title"].Value;
I suggest you to use LINQ to XML for parsing xml:
var xdoc = XDocument.Load("Settings.xml");
var titles = xdoc.XPathSelectElements("//park/car")
.Select(c => (string)c.Attribute("title"));
Or without XPath:
var titles = xdoc.Descendants("park")
.Elements("car")
.Select(c => (string)c.Attribute("title"));

Getting value of an attribute within namespace

I am trying to process the following XML:
<rif:Rif xmlns:rif="rif" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" rif:numeroRif="XYZXYZXYZ">
<rif:Nombre>Nombre</rif:Nombre>
<rif:AgenteRetencionIVA>SI</rif:AgenteRetencionIVA>
<rif:ContribuyenteIVA>SI</rif:ContribuyenteIVA>
<rif:Tasa />
</rif:Rif>
An I am using the next code:
XDocument doc = XDocument.Parse(result);
var q = from item in doc.Descendants()
let attributeType = item.Attribute("AgenteRetencionIVA").Value
select item;
I have problems to get the attribute rif:AgenteRetencionIVA. How do I to do it?
Looks like tou need to specify custom namespace:
string xml = #"...";
XName nameRif = "rif";
XDocument doc = XDocument.Parse(xml);
var q = from item in doc.Descendants()
let attributeType = item.Attribute(nameRif + "AgenteRetencionIVA")
select item.Value;
var a = q.ToArray();

C# XML How to retrive innerText of field by attribute?

Here is the XML sample:
<?xml version="1.0" ?>
<XMLScreen xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CX>80</CX>
<CY>24</CY>
<Formatted>true</Formatted>
<Field>
<Location position="1" left="1" top="0" length="69" />
<Attributes Base="226" Protected="false" FieldType="High" />
*SDC SCHEDULING CATEGORY UPDATE
</Field>
</XMLScreen>
I want to retrive the Inner text of each field based on its Location position.
What I have so far is:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(myEm.CurrentScreenXML.GetXMLText());
XmlNodeList fields = xmlDoc.GetElementsByTagName("Field");
MessageBox.Show("Field spot: " + i + " Contains: " + fields[i].InnerText);
And I want to be able to just extract the inner text of the field by passing in a number of the location position. So if I say foo[i] I want to be able to get the innertext
*SDC SCHEDULING CATEGORY UPDATE
You should use a xpath search query :
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
int nodeId = 4;
XmlNode node = xmlDoc.SelectSingleNode(String.Format(#"//Location[#position='{0}']", nodeId));
if (node != null)
{
String field = node.ParentNode.InnerText;
}
Something like that, with XDocument instead of XmlDocument (well, if you're not in .net 3.5 or higher, we'll have a problem).
private string GetTextByLocationId(XDocument document, int id)
{
var field = document.Descendants("Field").FirstOrDefault(m => m.Element("Location").Attribute("position").Value == id.ToString());
if (field == null) return null;
return field.Value;
}
and usage
var xDocument = XDocument.Load(<pathToXmlFile or XmlReader or string or ...>);
var result = GetTextByLocationId(xDocument, 1);
EDIT
or if you want a dictionary with :key = position / value = text
private static Dictionary<int, string> ParseLocationAndText(XDocument document)
{
var fields = document.Descendants("Field");
return fields.ToDictionary(
f => Convert.ToInt32(f.Element("Location").Attribute("position").Value),
f => f.Value);
}
Try,
XElement root = XElement.Parse(myEm.CurrentScreenXML.GetXMLText());
XElement field = root.XPathSelectElement(
string.Format("Field[Location/#position='{0}']", 1));
string text = field.Value;
You will need to use the following using to use XPath with XElements.
using System.Xml.XPath;

Categories

Resources