Read Array in XML in C# - c#

I'm trying to read arrays in an XML, but my code does not return results
XML :
<ArrayOfProductoModel
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/WebApi.Models">
<ProductoModel>
<descripcion>descripcion 1</descripcion>
<fecha_registro>2016-03-01</fecha_registro>
<id_producto>1</id_producto>
<id_proveedor>1</id_proveedor>
<nombre_producto>producto 1</nombre_producto>
<precio>200</precio>
</ProductoModel>
<ProductoModel>
<descripcion>descripcion 3</descripcion>
<fecha_registro>2016-08-02</fecha_registro>
<id_producto>3</id_producto>
<id_proveedor>3</id_proveedor>
<nombre_producto>producto 3</nombre_producto>
<precio>500</precio>
</ProductoModel>
</ArrayOfProductoModel>
Code :
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(content);
XmlNodeList nodelist = xDoc.SelectNodes("ArrayOfProductoModel/ProductoModel");
foreach (XmlNode node in nodelist)
{
MessageBox.Show(node.SelectSingleNode("descripcion").InnerText);
}
As I can read the array?

The problem is the imported namespace. You can ignore the namespace as explained here:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(content);
XmlNodeList nodelist = xDoc.DocumentElement.SelectNodes("*[local-name()='ProductoModel']");
foreach (XmlNode node in nodelist)
{
MessageBox.Show(node.SelectSingleNode("*[local-name()='descripcion']").InnerText);
}
Alternatively you can use an XmlNamespaceManager as explained here:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(content);
XmlNamespaceManager manager = new XmlNamespaceManager(xDoc.NameTable);
manager.AddNamespace("MYNS", "http://schemas.datacontract.org/2004/07/WebApi.Models");
XmlNodeList nodelist = xDoc.DocumentElement.SelectNodes("MYNS:ProductoModel", manager);
foreach (XmlNode node in nodelist)
{
MessageBox.Show(node.SelectSingleNode("MYNS:descripcion", manager).InnerText);
}

Another solution is to use Linq to XML
var xml = #"<ArrayOfProductoModel
xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""
xmlns=""http://schemas.datacontract.org/2004/07/WebApi.Models"">
<ProductoModel>
<descripcion>descripcion 1</descripcion>
<fecha_registro>2016-03-01</fecha_registro>
<id_producto>1</id_producto>
<id_proveedor>1</id_proveedor>
<nombre_producto>producto 1</nombre_producto>
<precio>200</precio>
</ProductoModel>
<ProductoModel>
<descripcion>descripcion 3</descripcion>
<fecha_registro>2016-08-02</fecha_registro>
<id_producto>3</id_producto>
<id_proveedor>3</id_proveedor>
<nombre_producto>producto 3</nombre_producto>
<precio>500</precio>
</ProductoModel>
</ArrayOfProductoModel>";
var xDoc = XDocument.Parse(xml);
var ns = xDoc.Root.Name.Namespace;
var nodelist = xDoc.Element(ns + "ArrayOfProductoModel").Elements(ns + "ProductoModel");
foreach (var node in nodelist)
{
MessageBox.Show(node.Element(ns + "descripcion").Value);
}
Don't forget to put namespace in front of local name.

At first, I think problem in
xDoc.LoadXml(content);
You try:
xDoc.Load(filePathXml);
Second, I think problem in
XmlNodeList nodelist = xDoc.SelectNodes("ArrayOfProductoModel/ProductoModel");
foreach (XmlNode node in nodelist)
{
MessageBox.Show(node.SelectSingleNode("descripcion").InnerText);
}
You try:
XmlNode rootNode = doc.SelectSingleNode(#"/ArrayOfProductoModel");
var listProductModel = rootNode.SelectNodes(#"ProductoModel");
foreach (XmlNode node in listProductModel)
{
MessageBox.Show(node.SelectSingleNode("descripcion").InnerText);
}

Related

How to read file string xml file with prefix

This is mycode. I want to get elements in string xml but i didn't. Please help me.
$
string xml = "<s:Envelope xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'><s:Body><GetCustomerInfoResponse xmlns='http://tempuri.org/'><GetCustomerInfoResult xmlns:a='http://schemas.datacontract.org/2004/07/PaymentGatewayEVNSPC' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'><a:Address>137 Phường Tân Xuyên</a:Address><a:Bills><a:BillInfo><a:Amount>1516682</a:Amount><a:BillCode>170810TD</a:BillCode><a:DenNgay i:nil='true'></a:DenNgay><a:HoaDonID>33045487</a:HoaDonID><a:Month>8</a:Month><a:SoHo>0</a:SoHo><a:TuNgay i:nil='true'></a:TuNgay><a:TyLeGia i:nil='true'></a:TyLeGia><a:Year>2017</a:Year></a:BillInfo><a:BillInfo><a:Amount>89000</a:Amount><a:BillCode>170810DC</a:BillCode><a:DenNgay i:nil='true'></a:DenNgay><a:HoaDonID>33045487</a:HoaDonID><a:Month>8</a:Month><a:SoHo>0</a:SoHo><a:TuNgay i:nil='true'></a:TuNgay><a:TyLeGia i:nil='true'></a:TyLeGia><a:Year>2017</a:Year></a:BillInfo><a:BillInfo><a:Amount>148028</a:Amount><a:BillCode>170810VC</a:BillCode><a:DenNgay i:nil='true'></a:DenNgay><a:HoaDonID>33045488</a:HoaDonID><a:Month>8</a:Month><a:SoHo>0</a:SoHo><a:TuNgay i:nil='true'></a:TuNgay><a:TyLeGia i:nil='true'></a:TyLeGia><a:Year>2017</a:Year></a:BillInfo></a:Bills><a:CustomerCode>PB14010040801</a:CustomerCode><a:DanhSo>44900L36</a:DanhSo><a:MaSoThue></a:MaSoThue><a:MaTram></a:MaTram><a:Name>Cơ Sở Mộc Thành Tài</a:Name><a:NganhNghe></a:NganhNghe><a:PhienGCS></a:PhienGCS><a:Session></a:Session><a:SoCongTo>14226305</a:SoCongTo><a:SoGhiChiSo>A1010D001</a:SoGhiChiSo></GetCustomerInfoResult></GetCustomerInfoResponse></s:Body></s:Envelope>";
window.jQuery
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
var ns = new XmlNamespaceManager(new NameTable());
// XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable);
ns.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
// ns.AddNamespace("xmlns","'http://tempuri.org/'");
ns.AddNamespace("a", "http://schemas.datacontract.org/2004/07/PaymentGatewayEVNSPC");
ns.AddNamespace("i", "http://www.w3.org/2001/XMLSchema-instance");
string xpath = "s:Envelope/s:Body/GetCustomerInfoResponse/GetCustomerInfoResult";
// string xpath = "myDataz/listS/sog";
var nodes = xmlDoc.SelectNodes(xpath,ns);
;
foreach (XmlNode childrenNode in nodes)
{
Console.Write(childrenNode.SelectSingleNode("a:Address",ns).InnerXml);
Console.Write("\n");
}
Unfortunately, in a namespaced document, you can't use XPath with the default namespace. See this answer for more info.
This works:
var ns = new XmlNamespaceManager(new NameTable());
ns.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
ns.AddNamespace("a", "http://schemas.datacontract.org/2004/07/PaymentGatewayEVNSPC");
ns.AddNamespace("i", "http://www.w3.org/2001/XMLSchema-instance");
//Add a prefix for the default namespace for GetCustomerInfoResponse and GeteCustomerInforResult
ns.AddNamespace("t","http://tempuri.org/");
string xpath = "s:Envelope/s:Body/t:GetCustomerInfoResponse/t:GetCustomerInfoResult";
var nodes = xmlDoc.SelectNodes(xpath, ns);
foreach (XmlNode childrenNode in nodes)
{
Console.Write(childrenNode.SelectSingleNode("a:Address", ns).InnerXml);
Console.Write("\n");
}

Query for unique id with XDocument

I have the following XML name Sample.xml which I am trying to query uniqueID with XDocument:
<Request>
<Person xmlns="http://CompanyName.AppName.version1" uniqueID="3221">
<AccountNo>83838</AccountNo>
<FirstName>Tom</FirstName>
<LastName>Jackson</LastName>
</Person>
<Person xmlns="http://CompanyName.AppName.version1" uniqueID="21132">
<AccountNo>789875</AccountNo>
<FirstName>Chris</FirstName>
<LastName>Smith</LastName>
</Person>
</Request>
How do i write code to extract uniqueID of all persons.
You can use LINQ to XML to retrieve the unique ID from your XML document.
string xml = "<Request><Person xmlns='http://CompanyName.AppName.version1' uniqueID='3221'><AccountNo>83838</AccountNo><FirstName>Tom</FirstName><LastName>Jackson</LastName></Person><Person xmlns='http://CompanyName.AppName.version1' uniqueID='21132'><AccountNo>789875</AccountNo><FirstName>Chris</FirstName><LastName>Smith</LastName></Person></Request>";
XDocument doc = XDocument.Parse(xml);
XNamespace ns = "http://CompanyName.AppName.version1";
var uniqueIDs = doc.Descendants(ns + "Person")
.Select(p => p.Attribute("uniqueID").Value)
.ToList();
Try below code With XmlDocument in place
string xml = "<Request><Person xmlns='http://CompanyName.AppName.version1' uniqueID='3221'><AccountNo>83838</AccountNo><FirstName>Tom</FirstName><LastName>Jackson</LastName></Person><Person xmlns='http://CompanyName.AppName.version1' uniqueID='21132'><AccountNo>789875</AccountNo><FirstName>Chris</FirstName><LastName>Smith</LastName></Person></Request>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Person");
foreach (XmlNode node in nodeList)
{
Console.WriteLine(node.Attributes["uniqueID"].Value);
}
You can get the Unique ID by:
string xml="Your XML String";
XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(xml));
XmlDocument doc = new XmlDocument();
XmlNode node = doc.ReadNode(reader);
foreach (XmlNode chldNode in node.ChildNodes)
{
if (chldNode.HasChildNodes)
{
foreach (XmlNode item in node.ChildNodes)
{
string uniqueID = chldNode.Attributes["uniqueID"].Value;
Response.Write(employeeName + "<br />");
}
}
}

Renaming xmlnodes using c# dynamically

I am using the below code to rename the xmlnode name dynamically. It's looping though the xml just fine, but it does not change the node name. Please help me to do this.
Sample XML doucment
- <NewDataSet>
- <Table5>
<FLD_ID>62</FLD_ID>
<FLD_DATE>2013-03-12</FLD_DATE>
<FLD_MOD_DATE>2013-04-05</FLD_MOD_DATE>
<FLD_DESC>New Creation</FLD_DESC>
</Table5>
- </NewDataSet>
Needed XML DOCUMENT
- <rows>
- <row>
<cell>62</cell>
<cell>2013-03-12</cell>
<cell>2013-04-05</cell>
<cell>New Creation</cell>
</row>
- </rows>
My code is here
XmlNode PackageListNode = hst_doc.SelectSingleNode("NewDataSet");
XmlNodeList PackageNodeList = PackageListNode.SelectNodes("Table5");
foreach (XmlNode node in PackageNodeList)
{
node.Name.Replace("Table5", "row");
foreach (XmlNode ls in node)
{
ls.Name.Replace(ls.Name, "cell");
}
}
As you can't replace element names in an XmlDocument...
...a replacement approach for your specific situation:
string srcXML = "<NewDataSet><Table5><FLD_ID>62</FLD_ID><FLD_DATE>2013-03-12</FLD_DATE><FLD_MOD_DATE>2013-04-05</FLD_MOD_DATE><FLD_DESC>New Creation</FLD_DESC></Table5></NewDataSet>";
var doc = new XmlDocument();
doc.LoadXml(srcXML);
XmlNode oldRoot = doc.SelectSingleNode("NewDataSet");
XmlNode newRoot = doc.CreateElement("rows");
doc.ReplaceChild(newRoot, oldRoot);
foreach (XmlNode childNode in oldRoot.ChildNodes)
{
newRoot.AppendChild(childNode.CloneNode(true));
}
XmlNodeList PackageNodeList = newRoot.SelectNodes("Table5");
foreach (XmlNode node in PackageNodeList)
{
var newNode = doc.CreateElement("row");
newRoot.ReplaceChild(newNode, node);
foreach (XmlNode childNode in node.ChildNodes)
{
var clonedChildNode = childNode.CloneNode(true);
newNode.AppendChild(clonedChildNode);
var newChildNode = doc.CreateElement("cell");
newNode.ReplaceChild(newChildNode, clonedChildNode);
foreach (XmlNode childChildNode in clonedChildNode.ChildNodes)
{
newChildNode.AppendChild(childChildNode.CloneNode(true));
}
}
}
Debug.Print(doc.OuterXml);
Embrace LINQ, embrace it!
// load the document from a file
var doc = XDocument.Load(xmlPath);
var root = doc.Root;
// replace the root element with a new element
root.ReplaceWith(
// create a new element with
// the name "rows" with new children
new XElement("rows",
// replace all child elements of
// the root with new elements
root.Elements().Select(table =>
// replace the current element with a new element
// with the name "row" with the new children
new XElement("row",
// replace all child elements of the
// current element with new elements
table.Elements().Select(field =>
// replace the current element with a new element
// with the name "cell" with the same value
new XElement("cell",
(string)field
)
)
)
)
)
);
// save the document back to the file
doc.Save(xmlPath);
String.Replace returns a new string, so of course one would love to:
node.Name = node.Name.Replace("Table5", "row");
which might as well be
node.Name = "row";
however, if you look at the documentation it says that XmlNode.Name is purely a 'getter' and not a 'setter', so maybe you'll need to create whole new nodes to replace them, it depends on the actual implementation, since XmlNode is an abstract class.
for (int i = 0; i < PackageNodeList.Count; ++i) XmlNode node in PackageNodeList)
{
XmlNode replacementNode = new XmlNode("row");
foreach (XmlNode ls in node)
{
XmlNode newCell = new XmlNode("cell");
newCell.Value = ls.Value;
replacementNode.AppendChild(newCell);
}
PackageNodeList[i] = replacementNode
PackageNodeList[i].ParentNode.ReplaceChild(PackageNodeList[i], replacementNode);
}

How to add nodes with the same name in a loop?

I'm trying to create the following XML file:
<Clientes>
<Cliente>
<Name>sfsdfsd</Name>
<Phone>
</Phone>
<Matriculas>
<Matricula>
<Nr>567856786</Nr>
<Marca>86786</Marca>
<Modelo>8678678</Modelo>
</Matricula>
<Matricula>
<Nr>u56u5u</Nr>
<Marca>4564b5</Marca>
<Modelo>b456b</Modelo>
</Matricula>
</Matriculas>
</Cliente>
</Clientes>
I have several clientes stored in a List and each of them may have more then one Matricula, stored in a List
i have the following code:
foreach (Cliente c in cli)
{
XmlNode xCliente = xDoc.CreateElement("Cliente");
XmlNode xName = xDoc.CreateElement("Name");
XmlNode xPhone = xDoc.CreateElement("Phone");
XmlNode xMatriculas = xDoc.CreateElement("Matriculas");
XmlNode xMatricula = xDoc.CreateElement("Matricula");
XmlNode xNr = xDoc.CreateElement("Nr");
XmlNode xMarca = xDoc.CreateElement("Marca");
XmlNode xModelo = xDoc.CreateElement("Modelo");
xName.InnerText = c.Name;
xPhone.InnerText = c.Phone;
xCliente.AppendChild(xName);
xCliente.AppendChild(xPhone);
foreach (Matricula m in c.matricula)
{
xNr.InnerText = m.nr;
xMarca.InnerText = m.marca;
xModelo.InnerText = m.modelo;
xMatricula.AppendChild(xNr);
xMatricula.AppendChild(xMarca);
xMatricula.AppendChild(xModelo);
xMatriculas.AppendChild(xMatricula);
}
xCliente.AppendChild(xMatriculas);
xDoc.DocumentElement.AppendChild(xCliente);
}
i can add several Cliente to the root, but only the last Matricula in Matriculas is added.
Move
XmlNode xMatricula = xDoc.CreateElement("Matricula");
XmlNode xNr = xDoc.CreateElement("Nr");
XmlNode xMarca = xDoc.CreateElement("Marca");
XmlNode xModelo = xDoc.CreateElement("Modelo");
inside the inner for loop.
You are reusing the exact same node, you need to create a new node every time you want a new node in your document.

Deleting XML using a selected Xpath and a for loop

I currently have the following code:
XPathNodeIterator theNodes = theNav.Select(theXPath.ToString());
while (theNodes.MoveNext())
{
//some attempts i though were close
//theNodes.RemoveChild(theNodes.Current.OuterXml);
//theNodes.Current.DeleteSelf();
}
I have set xpath to what I want to return in xml and I want to delete everything that is looped. I have tried a few ways of deleting the information but it does't like my syntax. I found an example on Microsoft support: http://support.microsoft.com/kb/317666 but I would like to use this while instead of a for each.
Any comments or questions are appreciated.
Why not to use XDocument?
var xmlText = "<Elements><Element1 /><Element2 /></Elements>";
var document = XDocument.Parse(xmlText);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
var result = document.ToString();
result will be <Elements><Element2 /></Elements>.
Or:
var document = XDocument.Load(fileName);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
document.Savel(fileName);
[Edit] For .NET 2, you can use XmlDocument:
XmlDocument document = new XmlDocument();
document.Load(fileName);
XmlNode node = document.SelectSingleNode("Elements/Element1");
node.ParentNode.RemoveChild(node);
document.Save(fileName);
[EDIT]
If you need to remove all child elements and attributes:
XmlNode node = document.SelectSingleNode("Elements");
node.RemoveAll();
If you need to keep attributes, but delete elements:
XmlNode node = document.SelectSingleNode("Elements");
foreach (XmlNode childNode in node.ChildNodes)
node.RemoveChild(childNode);
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);
XmlNode node = document.SelectSingleNode(nodeXPath);
node.RemoveAll();
XmlNode parentnode = node.ParentNode;
parentnode.RemoveChild(node);
document.Save("File Path");
You can use XmlDocument:
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);//or document.LoadXml(...
XmlNode node = document.SelectSingleNode(nodeXPath);
if (node.HasChildNodes)
{
//note that you can use node.RemoveAll(); it will remove all child nodes, but it will also remove all node' attributes.
for (int childNodeIndex = 0; childNodeIndex < node.ChildNodes.Count; childNodeIndex++)
{
node.RemoveChild(node.ChildNodes[childNodeIndex]);
}
}
document.Save("your file path"));

Categories

Resources