how to get xml nth element name in wpf - c#

public partial class XML_3 : Window
{
public XML_3()
{
this.InitializeComponent();
XmlDocument doc = new XmlDocument();
doc.Load("D:/sample.xml");
XmlNodeList student_list = doc.GetElementsByTagName("Student");
foreach (XmlNode node in student_list)
{
XmlElement student = (XmlElement)node;
int element_count = student.ChildNodes.Count;
}
}
}
In above code.I can get the count of element except root element(Student). now the count is 3.
But i have to get 2ed element name(Kavi),it's attribute element name(ID) and it's child element name(FName,MName).
what should i do to get those stuff.
Please help me...

Use XDocument (why?):
var doc = XDocument.Parse(xml); // OR Load(...)
var nodeCount = doc.Elements().Count();
var secondNode = doc.Elements().Skip(1).First();
var studentName = secondNode.Name;
var studentId = secondNode.Attribute("ID").Value;
or (for your code):
var secondNode = student.ChildNodes[1] as XmlElement;
var studentName = secondNode.LocalName;
var studentId = secondNode.Attributes["ID"];
Added:
var secondNode = student.ChildNodes[1];
var fName =
secondNode.ChildNodes.Cast<XmlElement>().FirstOrDefault(x => x.LocalName == "FName").InnerText;
var mName =
secondNode.ChildNodes.Cast<XmlElement>().FirstOrDefault(x => x.LocalName == "MName").InnerText;
var studentId = secondNode.Attributes["ID"].Value;

Related

How to hold more than one values in XML element?

xWaarde.Value is overriding with new values and flushing old values.
how to stored multiple values in Xelement.
private XElement[] AddCoordinatenList(XElement childElements)
{
XmlNode xmlCoordinatenNode = Utility.GetMappingValues(Constants.BMCoordinaten, ConnectionType.BM);
XmlNode xWaardeNode = Utility.GetMappingValues(Constants.BMXwaarde, ConnectionType.BM);
XmlNode yWaardeNode = Utility.GetMappingValues(Constants.BMYwaarde, ConnectionType.BM);
XmlNode CoordinateX = Utility.GetMappingValues(Constants.XCoordinate, ConnectionType.BM);
XmlNode CoordinateY = Utility.GetMappingValues(Constants.YCoordinate, ConnectionType.BM);
var coordinatenList = from document in childElements.DescendantsAndSelf() where document.Name.LocalName == xmlCoordinatenNode.Name select document;
List<XElement> xcoordinatenList = new List<XElement>();
XElement xWaarde = new XElement(CoordinateX.Name);
XElement yWaarde = new XElement(CoordinateY.Name);
if (coordinatenList.Count() > 0)
{
foreach (XElement element in coordinatenList.Descendants())
{
if (element.Name.LocalName == xWaardeNode.Name)
{
xWaarde.Value = element.Value;
}
if (element.Name.LocalName == yWaardeNode.Name)
{
yWaarde.Value = element.Value;
}
}
}
return xcoordinatenList.ToArray();
}
It's not possible. Use Attributes:
XAttribute attribute = new XAttribute("name1", <value>);
element.Add(attribute);
attribute = new XAttribute("name2", <value>);
element.Add(attribute);
You can also add a list of child elements or add all strings as one string, separated by a comma for instance.

Nested XML from list with needed data on multiple lines

I need to format an XML to a given hierarchy from a list (List<>). The list contains, for the banking information, data spread across multiple rows as shown in the image.
The XML output needs to be formatted like this:
<ROOT>
<DocumentElement>
<Supplier>
<Company>STV</Company>
<Code>000199</Code>
<Name>TrafTrans</Name>
<BankAccounts>
<SupplierBankAccount>
<Bban>220-012510-63</Bban>
<Name>B1</Name>
</SupplierBankAccount>
<SupplierBankAccount>
<Bban>RUIL</Bban>
<Name>RUIL</Name>
</SupplierBankAccount>
</BankAccounts>
<SupplierAddresses>
<SupplierAddress>
<Type>PostalAddress</Type>
<Name>Loc TrafTrans</Name>
<IsDefault>true</IsDefault>
<AddressParts>
<SupplierAddressPart>
<AddressPartKey>STREET_NAME</AddressPartKey>
<AddressPartText>Somewhere</AddressPartText>
</SupplierAddressPart>
<SupplierAddressPart>
<AddressPartKey>COUNTRY</AddressPartKey>
<AddressPartText>SPAIN</AddressPartText>
</SupplierAddressPart>
</AddressParts>
</SupplierAddress>
</SupplierAddresses>
</Supplier>
</DocumentElement>
</ROOT>
I already have a method that converts a list to an XML and returns a string. But the problem is that this only formats one item from the list and there could be additional info in the following items.
public static string SuppliersToXML(List<SupplierItem> supplier)
{
CultureInfo ci = new CultureInfo("en-US");
XmlDocument doc = new XmlDocument();
var root = doc.CreateElement("ROOT");
var rootNode = doc.AppendChild(root);
var docElem = doc.CreateElement("DocumentElement");
var docElemNode = rootNode.AppendChild(docElem);
foreach (var item in supplier)
{
var supplierElem = doc.CreateElement("Supplier");
var companyElem = (XmlNode)doc.CreateElement("Company");
companyElem.InnerText = item.Company.ToString();
//more code...
supplierElem.AppendChild(companyElem);
//more code...
}
return doc.OuterXml;
}
I have found the answer myself, it may not be the prettiest code ever written. But it does the job.
public static string SuppliersToXML(List<SupplierItem> supplier)
{
//A distinct select is needed because bank info can be on multiple lines. So first a list is generated with correct info except for bank information
List<SupplierItem> distinctsupplier = supplier
.GroupBy(p => p.Code)
.Select(g => g.First())
.ToList();
CultureInfo ci = new CultureInfo("en-US");
XmlDocument doc = new XmlDocument();
var root = doc.CreateElement("ROOT");
var rootNode = doc.AppendChild(root);
var docElem = doc.CreateElement("DocumentElement");
var docElemNode = rootNode.AppendChild(docElem);
foreach (var item in distinctsupplier)
{
var supplierElem = doc.CreateElement("Supplier");
var companyElem = (XmlNode)doc.CreateElement("Company");
companyElem.InnerText = item.Company.ToString();
var codeElem = (XmlNode)doc.CreateElement("Code");
codeElem.InnerText = item.Code.ToString();
var codeName = (XmlNode)doc.CreateElement("Name");
codeName.InnerText = item.Name.ToString();
//supplieridentifier part
var supplierIdsElem = doc.CreateElement("SupplierIdentifiers");
var supplierIdElem = doc.CreateElement("SupplierIdentifier");
var supplierIdValueElem = (XmlNode)doc.CreateElement("SupplierIDValue");
supplierIdValueElem.InnerText = item.SupplierIDValue;
//supplieraddress part
var supplierAddressesElem = doc.CreateElement("SupplierAddresses");
var supplierAddressElem = doc.CreateElement("SupplierAddress");
var supplierTypeValueElem = (XmlNode)doc.CreateElement("Type");
supplierTypeValueElem.InnerText = item.Type;
var supplierNameValueElem = (XmlNode)doc.CreateElement("Name");
supplierNameValueElem.InnerText = item.AddressName;
var supplierDefaultValueElem = (XmlNode)doc.CreateElement("IsDefault");
supplierDefaultValueElem.InnerText = item.AddressIsDefault;
//address part
var AddressPartElem = doc.CreateElement("AddressParts");
var supplierAddressPartsElem = doc.CreateElement("SupplierAddressPart");
//Street
var AddressPartElemStreetKeyElem = (XmlNode)doc.CreateElement("AddressPartKey");
AddressPartElemStreetKeyElem.InnerText = item.AddressStreetKey;
var AddressPartElemStreetValueElem = (XmlNode)doc.CreateElement("AddressPartText");
AddressPartElemStreetValueElem.InnerText = item.AddressStreetText;
//Country
var AddressPartElemCountryKeyElem = (XmlNode)doc.CreateElement("AddressPartKey");
AddressPartElemCountryKeyElem.InnerText = item.AddressCountryKey;
var AddressPartElemCountryValueElem = (XmlNode)doc.CreateElement("AddressPartText");
AddressPartElemCountryValueElem.InnerText = item.AddressCountryText;
//add elements to supplierelem
supplierElem.AppendChild(companyElem);
supplierElem.AppendChild(codeElem);
supplierElem.AppendChild(codeName);
//bankaccounts part
var bankAccountElem = doc.CreateElement("BankAccounts");
//select all rows that contain multiple lines, so the bank info can be extracted, for a certain supplier
var bankInformation = supplier.Where(s => s.Code == item.Code).ToList();
foreach (var bankitem in bankInformation)
{
if (item.Code == bankitem.Code)
{
var bankAccountSupplElem = doc.CreateElement("SupplierBankAccount");
var bankAccountBbanElem = doc.CreateElement("Bban");
var bankAccountBbanValueElem = (XmlNode)doc.CreateElement("Bban");
bankAccountBbanValueElem.InnerText = bankitem.Bban;
var bankAccountNameElem = doc.CreateElement("Name");
var bankAccountNameValueElem = (XmlNode)doc.CreateElement("Name");
bankAccountNameValueElem.InnerText = bankitem.BankName;
var bankAccountElemNode = supplierElem.AppendChild(bankAccountElem);
var bankAccountSupplElemNode = bankAccountElemNode.AppendChild(bankAccountSupplElem);
bankAccountSupplElemNode.AppendChild(bankAccountBbanValueElem);
bankAccountSupplElemNode.AppendChild(bankAccountNameValueElem);
}
}
//add address elements to supplierelem
var supplierAddressesElemNode = supplierElem.AppendChild(supplierAddressesElem);
var supplierAddressElemNode = supplierAddressesElemNode.AppendChild(supplierAddressElem);
supplierAddressElemNode.AppendChild(supplierTypeValueElem);
supplierAddressElemNode.AppendChild(supplierNameValueElem);
supplierAddressElemNode.AppendChild(supplierDefaultValueElem);
//add addressparts to supplieraddressesnode
//Street
var AddressPartElemNode = supplierAddressElemNode.AppendChild(AddressPartElem);
var supplierAddressPartsElemNode = AddressPartElemNode.AppendChild(supplierAddressPartsElem);
supplierAddressPartsElemNode.AppendChild(AddressPartElemStreetKeyElem);
supplierAddressPartsElemNode.AppendChild(AddressPartElemStreetValueElem);
//Country (first reinitialize supplieraddresspart)
supplierAddressPartsElem = doc.CreateElement("SupplierAddressPart");
var supplierAddressPartsCountryElemNode = AddressPartElemNode.AppendChild(supplierAddressPartsElem);
supplierAddressPartsCountryElemNode.AppendChild(AddressPartElemCountryKeyElem);
supplierAddressPartsCountryElemNode.AppendChild(AddressPartElemCountryValueElem);
//add all supplierelements to docelemnode
docElemNode.AppendChild(supplierElem);
}
return doc.OuterXml;
}

How to get xml file from isolated in wp8

I Try to get Xml file and Bind to list
Here is my Xml File
- <data>
- <Bookmarkdata>
<Bookname>TheNfame</Bookname>
<Bookid>5a1df538-6e91-4a39-819d-e043c9881fb7</Bookid>
<Pageno>0</Pageno>
</Bookmarkdata>
- <Bookmarkdata>
<Bookname>TheNfame</Bookname>
<Bookid>5a1df538-6e91-4a39-819d-e043c9881fb7</Bookid>
<Pageno>1</Pageno>
</Bookmarkdata>
</data>
This is my code
private void GetBookMarkData()
{
var doc = new XDocument();
XDocument xdoc= new XDocument();
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
if (store.FileExists("BookmarkFile.xml"))
{
using (var sr = new StreamReader(new IsolatedStorageFileStream("BookmarkFile.xml", FileMode.OpenOrCreate, store)))
{
doc = XDocument.Load(sr);
// xdoc = XDocument.Load(sr);
var data = from query in doc.Descendants("data")
select new Bookmarkdata
{
Bookname = (string)query.Element("Bookname"),
Bookid = (string)query.Element("Bookid"),
BookPath = (string)query.Element("BookPath"),
Pageno = (int)query.Element("Pageno")
};
Bookmark_List.ItemsSource = data;
}
}
}
catch
(Exception ex) { }
}
But in Catch return a error
Value cannot be null.
Parameter name: element
In my code doc = XDocument.Load(sr);
i have get a xml data dubag time but in next line is error Please Help
Your LINQ-to-XML query is a bit off. query variable represent <data> element here :
var data = from query in doc.Descendants("data")
select new Bookmarkdata
{
Bookname = (string)query.Element("Bookname"),
Bookid = (string)query.Element("Bookid"),
BookPath = (string)query.Element("BookPath"),
Pageno = (int)query.Element("Pageno")
};
so it doesn't have direct child named Bookname, Bookid, BookPath, or Pageno. I guess you want to select from <Bookmarkdata> elements instead :
var data = from query in doc.Descendants("Bookmarkdata")
select new
{
Bookname = (string)query.Element("Bookname"),
Bookid = (string)query.Element("Bookid"),
BookPath = (string)query.Element("BookPath"),
Pageno = (int)query.Element("Pageno")
};

using xmldocument to read xml

<?xml version="1.0" encoding="utf-8" ?>
<testcase>
<date>4/12/13</date>
<name>Mrinal</name>
<subject>xmlTest</subject>
</testcase>
I am trying to read the above xml using c#, But i get null exception in the try catch block can any body suggest the required change.
static void Main(string[] args)
{
XmlDocument xd = new XmlDocument();
xd.Load("C:/Users/mkumar/Documents/testcase.xml");
XmlNodeList nodelist = xd.SelectNodes("/testcase"); // get all <testcase> nodes
foreach (XmlNode node in nodelist) // for each <testcase> node
{
CommonLib.TestCase tc = new CommonLib.TestCase();
try
{
tc.name = node.Attributes.GetNamedItem("date").Value;
tc.date = node.Attributes.GetNamedItem("name").Value;
tc.sub = node.Attributes.GetNamedItem("subject").Value;
}
catch (Exception e)
{
MessageBox.Show("Error in reading XML", "xmlError", MessageBoxButtons.OK);
}
........
.....
The testcase element has no attributes. You should be looking to it's child nodes:
tc.name = node.SelectSingleNode("name").InnerText;
tc.date = node.SelectSingleNode("date").InnerText;
tc.sub = node.SelectSingleNode("subject").InnerText;
You might process all nodes like this:
var testCases = nodelist
.Cast<XmlNode>()
.Select(x => new CommonLib.TestCase()
{
name = x.SelectSingleNode("name").InnerText,
date = x.SelectSingleNode("date").InnerText,
sub = x.SelectSingleNode("subject").InnerText
})
.ToList();
You can use LINQ to XML to select all testcase elements from your xml and parse them to TestCase instances:
var xdoc = XDocument.Load("C:/Users/mkumar/Documents/testcase.xml");
var testCases = from tc in xdoc.Descendants("testcase")
select new CommonLib.TestCase {
date = (string)tc.Element("date"),
name = (string)tc.Element("name"),
sub= (string)tc.Element("subject")
};
BTW you have only one testcase element currently, which is root of XML file. So, you can do instead:
var tc = XElement.Load("C:/Users/mkumar/Documents/testcase.xml");
var testCase = new CommonLib.TestCase {
date = (string)tc.Element("date"),
name = (string)tc.Element("name"),
sub= (string)tc.Element("subject")
};
private static void Main(string[] args)
{
XmlDocument xd = new XmlDocument();
xd.Load("C:\\test1.xml");
XmlNodeList nodelist = xd.SelectNodes("/testcase"); // get all <testcase> nodes
foreach (XmlNode node in nodelist) // for each <testcase> node
{
try
{
var name = node.SelectSingleNode("date").InnerText;
var date = node.Attributes.GetNamedItem("name").Value;
var sub = node.Attributes.GetNamedItem("subject").Value;
}
catch (Exception e)
{
MessageBox.Show("Error in reading XML", "xmlError", MessageBoxButtons.OK);
}
}
This will work I have test it #Alex correct answer
You are trying to read attributes whereas date, name and subject are not attributes. They are subnodes.
your code should be like this
XmlDocument xd = new XmlDocument();
xd.Load("test.xml");
XmlNodeList nodelist = xd.SelectNodes("/testcase"); // get all <testcase> nodes
foreach (XmlNode node in nodelist) // for each <testcase> node
{
try
{
string name = node.SelectSingleNode("name").InnerText;
string date = node.SelectSingleNode("date").InnerText;
string sub = node.SelectSingleNode("subject").InnerText;
}
catch (Exception ex)
{
MessageBox.Show("Error in reading XML", "xmlError", MessageBoxButtons.OK);
}
}
Your Xml do not contain Attributes. date, name and subject - it's Child Nodes of the testcase Node.
Try this:
...
tc.name = node["name"].InnerText;
...
or this:
...
tc.name = node.SelectSingleNode("name").InnerText;
...

Adding Subroot elements in XML

I'm making an XML Document which contains subroot nodes. I'm using XmlDocument and adding the child nodes.
This is my code:
XmlDocument doc = new XmlDocument();
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec);
XmlElement root = doc.CreateElement("LICENSE");
if (strGInfo == "")
{
strGInfo = "N/A";
}
XmlElement ginfo = doc.CreateElement("GENERAL_INFO");
ginfo.InnerText = strGInfo;
root.AppendChild(ginfo);
if (strLNo == "")
{
strLNo = "N/A";
}
XmlElement subroot = doc.CreateElement("LICENSE_INFO");
//XmlElement root1 = doc.CreateElement("LICENSE_INFO");
XmlElement lno = doc.CreateElement("LICENCE_NO");
lno.InnerText = txtLNo.Text;
subroot.AppendChild(lno);
if (strUID == "")
{
strUID = "N/A";
}
XmlElement uid = doc.CreateElement("USER_ID");
uid.InnerText = txtUID.Text;
subroot.AppendChild(uid);
if (strOrg == "")
{
strOrg = "N/A";
}
XmlElement org = doc.CreateElement("ORGANIZATION");
org.InnerText = txtOrg.Text;
subroot.AppendChild(org);
if (strUName == "")
{
strUName = "N/A";
}
XmlElement uname = doc.CreateElement("USER_NAME");
uname.InnerText = txtUName.Text;
subroot.AppendChild(uname);
if (strSType == "")
{
strSType = "N/A";
}
XmlElement stype = doc.CreateElement("SOLUTION_TYPE");
stype.InnerText = txtSType.Text;
subroot.AppendChild(stype);
if (strVer == "")
{
strVer = "N/A";
}
XmlElement ver = doc.CreateElement("VERSION");
ver.InnerText = txtVer.Text;
subroot.AppendChild(ver);
XmlElement ltype = doc.CreateElement("LICENCE_TYPE");
ltype.InnerText = drpLType.SelectedItem.Text;
subroot.AppendChild(ltype);
if (strMeapSupp == "")
{
strMeapSupp = "N/A";
}
XmlElement meapsupp = doc.CreateElement("MEAP_SUPPORT");
meapsupp.InnerText = rdoMeapSupport.Text;
subroot.AppendChild(meapsupp);
XmlElement LicFrom = doc.CreateElement("LICENCE_FROM");
LicFrom.InnerText = lblLFrom.Text;
subroot.AppendChild(LicFrom);
XmlElement LicTo = doc.CreateElement("LICENCE_TO");
LicTo.InnerText = lblLTo.Text;
subroot.AppendChild(LicTo);
XmlElement suppfrom = doc.CreateElement("SUPPORT_FROM");
suppfrom.InnerText = lblSuppFrom.Text;
subroot.AppendChild(suppfrom);
XmlElement suppto = doc.CreateElement("SUPPORT_TO");
suppto.InnerText = lblSuppTo.Text;
subroot.AppendChild(suppto);
doc.AppendChild(subroot);
XmlElement subroot2 = doc.CreateElement("LICENCE_CONSTRAINT");
if (strMaxUsr == "")
{
strMaxUsr = "N/A";
}
XmlElement maxusr = doc.CreateElement("MAX_USER");
maxusr.InnerText = txtMaxUsr.Text;
subroot2.AppendChild(maxusr);
if (strMaxMach == "")
{
strMaxMach = "N/A";
}
XmlElement maxmach = doc.CreateElement("MAX_MACHINE");
maxmach.InnerText = txtMaxMach.Text;
subroot2.AppendChild(maxmach);
if (strMachIP == "")
{
strMachIP = "N/A";
}
doc.AppendChild(subroot2);
XmlElement subroot3 = doc.CreateElement("MACHINE_INFO");
XmlElement machip = doc.CreateElement("MACHINE_IP");
machip.InnerText = txtMachIP.Text;
subroot3.AppendChild(machip);
if (strMachMac == "")
{
strMachMac = "N/A";
}
XmlElement machmac = doc.CreateElement("MACHINE_MAC");
machmac.InnerText = txtMachMac.Text;
subroot3.AppendChild(machmac);
doc.AppendChild(subroot3);
XmlElement subroot4 = doc.CreateElement("LICENCE_SIGNATURE");
XmlElement UqID = doc.CreateElement("UNIQUE_ID");
UqID.InnerText = txtUqID.Text;
subroot4.AppendChild(UqID);
doc.AppendChild(subroot4);
doc.Save(#"D:\New.xml");
My XML Document should look something like this:
-<LICENSE>
<GENERAL_INFO> </GENERAL INFO>
-<LICENSE_INFO>
<LICENSE_NO> </LICENSE_NO>
<USER_ID> </USER_ID> //etc
-<LICENCE_CONSTRAINT>
<MAX_USER> </MAX_USER>
<MAX_MACHINE> </MAX_MACHINE>
</LICENCE_CONSTRAINT>
-<MACHINE_INFO>
<MACHINE_IP> </MACHINE_IP>
<MACHINE_MAC> </MACHINE_MAC>
</MACHINE_INFO>
</LICENSE_INFO>
Where am I going wrong?
I would use Linq2Xml for this
string xml = FormXml(licenceNo: "1",machineIP:"1.2.3.4",generalInfo:"some Info");
public string FormXml(
string generalInfo="N/A",
string licenceNo="N/A",
string userID="N/A",
string maxUser="N/A",
string maxMachine="N/A",
string machineIP="N/A",
string machineMAC="N/A")
{
return new XElement("LICENSE",
new XElement("GENERAL_INFO", generalInfo),
new XElement("LICENSE_INFO",
new XElement("LICENSE_NO", licenceNo),
new XElement("USER_ID", userID)),
new XElement("LICENCE_CONSTRAINT",
new XElement("MAX_USER", maxUser),
new XElement("MAX_MACHINE", maxMachine)),
new XElement("MACHINE_INFO",
new XElement("MACHINE_IP", machineIP),
new XElement("MACHINE_MAC", machineMAC))).ToString();
}
and OUTPUT:
<LICENSE>
<GENERAL_INFO>some Info</GENERAL_INFO>
<LICENSE_INFO>
<LICENSE_NO>1</LICENSE_NO>
<USER_ID>N/A</USER_ID>
</LICENSE_INFO>
<LICENCE_CONSTRAINT>
<MAX_USER>N/A</MAX_USER>
<MAX_MACHINE>N/A</MAX_MACHINE>
</LICENCE_CONSTRAINT>
<MACHINE_INFO>
<MACHINE_IP>1.2.3.4</MACHINE_IP>
<MACHINE_MAC>N/A</MACHINE_MAC>
</MACHINE_INFO>
</LICENSE>
you are creating your root element "LICENSE":
XmlElement root = doc.CreateElement("LICENSE");
but you're not appending it to doc.
Furthermore, you are appending to doc multiple times:
doc.AppendChild(subroot);
...
doc.AppendChild(subroot2);
...
doc.AppendChild(subroot3);
which is not possible since an XML document can have only 1 root.
Add your root element like so:
XmlElement root = doc.CreateElement("LICENSE");
doc.AppendChild(root);
And change every doc.AppendChild() lateron into root.AppendChild()
And I have to agree with L.B.: LINQ to XML is much easier for stuff like this (but that wasn't the question ;) )

Categories