I have the below XML as:
<Requests xmlResponse="true">
<Request response="yes" responsewait="120000" sequence="1" type="Fulfillment">
<RequestData>
<PrintControl>FTP</PrintControl>
<User>81DF</User>
<Documents>
<AddressChangeLetter>
<DocumentInfo>
<AddressChange AddressChangeId="109346" Branch="418" LastChangeDate="">
<Name>AAA NOVAK</Name>
<TaxID>123123121</TaxID>
<OldAddress1>BOX 216</OldAddress1>
<OldAddress2>NYANE 68017</OldAddress2>
<OldAddress3 />
<OldAddress4 />
<NewAddress1>P O BOX 216</NewAddress1>
<NewAddress2>CERESCO NE 68017</NewAddress2>
<NewAddress3 />
<NewAddress4 />
<DateChanged>05/08/2013</DateChanged>
<AccountInfo AcctNum="231232311" AcctStatusCodes="IX" />
</AddressChange>
</DocumentInfo>
</AddressChangeLetter>
</Documents>
</RequestData>
I wanted to get the name or the value which is under the tag "Documents". Since in the above XML, the tag under the "Document" tag is "AddressChangeLetter", therefore, I want to get this name. How will I do it.
Something along the lines of... (it's not perfect, but it'll get you started - Google the functions I've used to get it working properly):
XmlDocument xml = new XmlDocument();
xml.Load(yourPathGoesHere)
XmlNodeList addressNodes = xml.GetElementsByTagName("AddressChange");
foreach (XmlNode oneNode in addressNodes) {
myVariableToGrabNames = oneNode["Name"].InnerText;
}
This can be done pretty easily using Linq to XML e.g.
var xml = ...;
var xdoc = XDocument.Parse(xml);
foreach (var e in xdoc.Descendants("Documents").Elements())
{
var name = e.Name; // AddressChangeLetter
}
Related
I have the following XML in a file called C:\temp\config.xml:
<?xml version="1.0" encoding="utf-8"?>
<dvp:systemConfig xmlns:devop="urn:foo.com:sys:rules">
<dvp:map id="rootFolderMap">
<dvp:entry key="anything" value="folder1"/>
<dvp:entry key="config" value="folder2"/>
<dvp:defaultValue value="folder1" />
</dvp:map>
<dvp:map id="folderMappings">
<dvp:entry key="SYS" value="System" />
<dvp:entry key="OPS" value="Operations" />
<dvp:entry key="DEV" value="Development" />
<dvp:defaultValue value="Miscellaneous" />
</dvp:map>
</dvp:systemConfig>
I am now trying to write C# code that will extract values from this XML. In particular, the list of value properties in the nodes.
List<string> folderNames = new List<string>
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\temp\config.xml");
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
XmlNodeList xmlNodeList =
doc.SelectNodes("/systemConfig/map[#id='folderMappings']/entry",nsMgr);
foreach (XmlNode xmlNode in xmlNodeList)
{
// I'm hoping xmlNodeList now contains a list of <dvp:entry> nodes.
string folderName = xmlNode.Attributes["value"].ToString().Trim();
folderNames.Add(folderName);
}
However, this code returns an empty xmlNodeList, so the final loop has no items.
I'm not sure how to use the XmlNamespaceManager to pick up the "dvp" prefix, or whether it figures this out when it loads the XmlDocument from the XML on disk.
Can anyone give me some guidance how one goes about using xpath to retrieve values for xml with prefixed nodes? Unfortunately I do not have the power to change the format of the XML so I have to work with the xml I'm provided with.
thanks heaps,
David.
you can ignore the namespace using local-name()
XmlNodeList xmlNodeList =
doc.SelectNodes("/*[local-name()='systemConfig']/*[local-name()='map'][#id='folderMappings']");
I have Multiple XML Files that look like below
<?xml version="1.0" encoding="UTF-8"?>
<schema>
<sp_transaction_id name="sp_transaction_id" value="1" />
<sp_year name="sp_year" value="2015" />
<sp_first_name name="sp_first_name" value="James" />
<sp_gender name="sp_gender" value="Male" />
<sp_date_of_birth name="sp_date_of_birth" value="06-06-1999" />
</schema>
The XML Format i think is in Key-Value Pairs.
I want to extract these values and store it into a database(SQL Server 2012) table, with the name(eg; sp_year) as Column Name and value(eg; 2015) as the Column value using ASP.NET C#.
I think i can upload the file and read it like this :
string fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
string filePath = Server.MapPath("~/Uploads/") + fileName;
FileUpload1.SaveAs(filePath);
string xml = File.ReadAllText(filePath);
But thats pretty much it ( Sorry Im a beginner ). Please Guide me. Thanks
You can use the following code to get the key value pairs
XDocument doc = XDocument.Load(filePath);
var schemaElement = doc.Element("schema");
foreach (var xElement in schemaElement.Elements())
{
Console.WriteLine(xElement.Attribute("name").Value + ":" + xElement.Attribute("value").Value);
}
Elements method returns all elements inside schema element.
However I suggest changing xml file to this format, if possible
<?xml version="1.0" encoding="UTF-8"?>
<schema>
<KeyValuePair name="sp_transaction_id" value="1" />
<KeyValuePair name="sp_year" value="2015" />
<KeyValuePair name="sp_first_name" value="James" />
<KeyValuePair name="sp_gender" value="Male" />
<KeyValuePair name="sp_date_of_birth" value="06-06-1999" />
</schema>
For reading data from an xml file you don't need to upload it.You can give path of xml and read from it.You can use following method to read from xml
public static XmlDocument LoadXmlDocument(string xmlPath)
{
if ((xmlPath == "") || (xmlPath == null) || (!File.Exists(xmlPath)))
return null;
StreamReader strreader = new StreamReader(xmlPath);
string xmlInnerText = strreader.ReadToEnd();
strreader.Close();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlInnerText);
return xmlDoc;
}
For reading data from xml you can use
XmlDocument xmlDoc = LoadXmlDocument(xmlPath);
XmlNodeList nodes = xmlDoc .SelectNodes("//*");
foreach (XmlElement node in nodes)
{
.
.
.
}
In foreach loop you can get your required values e.g sp_year
The answer below shows how to create an XmlDocument from it.
I would suggest to use it as a User-Defined class if you know whether Xml schema change.
First of all you should create POCO class appropriate to Xml file schema using XmlAnnotations.
Secondly:
Having path of the file:
XmlSerializer serializer = new XmlSerializer(typeof(definedclass));
using (FileStream fs = File.Open(pathtofile))
using (XmlReader reader = XmlReader.Create(fs))
{
var xmlObject = serializer.Deserialize(reader);
}
xmlObject is now your user-defined class with values from xml.
Regards,
Rafal
You can load the files into an XDocument & then use Linq-To-XML to extract the required information. The example code below loads all name/value pairs into an array of class :
class MyXMLClass
{
public String FieldName { get; set; }
public String Value { get; set; }
}
The code gets all "schema" descendants (just one as it is the top level element), then selects all elements inside the & creates a new class object for each extracting the name & value.
XDocument xd = XDocument.Load("test.xml");
MyXMLClass[] xe =
xd.Descendants("schema")
.Elements()
.Select(n => new MyXMLClass {FieldName = n.Attribute("name").Value, Value = n.Attribute("value").Value})
.ToArray();
I have looked everywhere, and cannot find anything to help me.
I am writing a program that connects to a webservice and then the webservice sends an XML response. After the response is received I have to retrieve certain values from it, but this is where it gets tricky
Here is a snippet of the returned XML:
<?xml version="1.0"?>
<MobilePortalSellingCategoriesHierarchy xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Response xmlns="http://blabla.com/service/">Successful</Response>
<ResponseNumber xmlns="http://blabla.com/service/">0</ResponseNumber>
<SellingCategoriesHierarchy xmlns="http://tym2sell.com/PortalService/">
<Response>Successful</Response>
<ResponseNumber>0</ResponseNumber>
<SellingCategories>
<PortalSellingCategory>
<SellingCategoryId xsi:nil="true" />
<SellingCategoryName>category1</SellingCategoryName>
<DeliveryMethod />
<DeliveryMethodNumber>0</DeliveryMethodNumber>
<SellingCategories>
<PortalSellingCategory>
<SellingCategoryId xsi:nil="true" />
<SellingCategoryName>category1_Item</SellingCategoryName>
<DeliveryMethod />
<DeliveryMethodNumber>0</DeliveryMethodNumber>
<SellingCategories>
<PortalSellingCategory>
<SellingCategoryId>2</SellingCategoryId>
<SellingCategoryName>Item2</SellingCategoryName>
<DeliveryMethod>Display</DeliveryMethod>
<DeliveryMethodNumber>1</DeliveryMethodNumber>
<VoucherValue>0.00</VoucherValue>
<IsVariablePrice>true</IsVariablePrice>
<MinimumVoucherValue>1.00</MinimumVoucherValue>
<MaximumVoucherValue>1000.00</MaximumVoucherValue>
<VoucherValueIncrement>1.00</VoucherValueIncrement>
<AdditionalInputItems>
<PortalAdditionalInputItem>
<InputItemId>-1</InputItemId>
<Label>Value:</Label>
<IsNumericOnly>true</IsNumericOnly>
<MaximumLength>7</MaximumLength>
<Hidden>false</Hidden>
</PortalAdditionalInputItem>
<PortalAdditionalInputItem>
<InputItemId>4</InputItemId>
<Label>Mobile Number</Label>
<IsNumericOnly>true</IsNumericOnly>
<MaximumLength>15</MaximumLength>
<Hidden>false</Hidden>
</PortalAdditionalInputItem>
</AdditionalInputItems>
<TwoStep>false</TwoStep>
<SelectedIcon>SamplePicture</SelectedIcon>
<UnSelectedIcon>SamplePicture</UnSelectedIcon>
This repeats from the SellingCategories node just under Response for a couple of times.
Here is a Snippet of my code where I get the XML as string.
XmlDocument xml = new XmlDocument();
xml.LoadXml(receivedData);
XmlNodeList xnList = xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy");
foreach (XmlNode xn in xnList)
{
string sellingCategoryName = xn["SellingCategoryName"].InnerText;
string SelectedIcon = xn["SelectedIcon"].InnerText;
string UnSelectedIcon = xn["UnSelectedIcon"].InnerText;
richTextBox1.AppendText(string.Format("Name: {0} {1} {2}", sellingCategoryName, SelectedIcon, UnSelectedIcon));
}
I have tried changing xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy");
to
xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy/SellingCategoriesHierarchy/SellingCategories/PortalSellingCategory");
I need to select each SellingCategoryName and list the SellingCategoryName(s) and all the other items underneath it.
I was hoping to get something in the lines of:
Category1
Category1_Item
Item2
SamplePicture
Sample Picture
Mine only reads the First Node and then returns "Successful" to me.
I havve also tried:
XElement root = XElement.Load("FilePath");
var sellingCategoryNames = from PortalSellingCategory in root.Elements("MobilePortalSellingCategoriesHierarchy")
where (string)PortalSellingCategory.Element("SellingCategoriesHierarchy").Element("SellingCategories").Element("PortalSellingCategory") != ""
select PortalSellingCategory;
foreach (var xEle in sellingCategoryNames)
{
richTextBox1.Text = (string)xEle;
}
Any help would be greatly appreciated.
What you are doing with
xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy");
is selecting your root node, which is just one. Thats why you only get one item in your list back. Is the hierarchy important? I can see that PortalSellingCategory can also be inside another PortalSellingCategory. If not maybe you could try the following select:
xml.SelectNodes("//PortalSellingCategory");
This will search for every node named "PortalSellingCategory" in your response, no mather where in the hierarchy it is.
EDIT:
And yes, you should look out for the namespaces, sry for didnt seeing that.
If you like geeting all the nodes with XPath you must create a new NamespaceManager and at it to your selectNodes call:
XmlDocument xml = new XmlDocument();
xml.LoadXml(data);
XmlNamespaceManager ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("ns", "http://tym2sell.com/PortalService/");
XmlNodeList xnList = xml.SelectNodes("//ns:PortalSellingCategory", ns);
I would use XElement instead of XMLDocument, and then use Linq to query or pick the elmements like: XElement xContact = ....
int contactno = (int?)xContact.Element("command").Element("contactperson").Attribute("contactpersonid") ?? -1;
if (xContact.Element("command").Element("contactperson").Element("name").Element("firstname") != null)
console.writeline(xContact.Element("command").Element("contactperson").Element("name").Element("firstname").Value);
var doc= new XmlDocument();
doc.Load("FilePath");
var nodeList = xml.GetElementsByTagName("PortalSellingCategory");
Hi,
It returns the collection of nodes, and you just have to query it to get needed informations.
Feel free to ask help if needed.
Dimitri.
Considering the following XML:
<Stations>
<Station>
<Code>HT</Code>
<Type>123</Type>
<Names>
<Short>H'bosch</Short>
<Middle>Den Bosch</Middle>
<Long>'s-Hertogenbosch</Long>
</Names>
<Country>NL</Country>
</Station>
</Stations>
There are multiple nodes. I need the value of each node.
I've got the XML from a webpage (http://webservices.ns.nl/ns-api-stations-v2)
Login (--) Pass (--)
Currently i take the XML as a string and parse it to a XDocument.
var xml = XDocument.Parse(xmlString);
foreach (var e in xml.Elements("Long"))
{
var stationName = e.ToString();
}
You can retrieve "Station" nodes using XPath, then get each subsequent child node using more XPath. This example isn't using Linq, which it looks like you possibly are trying to do from your question, but here it is:
XmlDocument xml = new XmlDocument();
xml.Load(xmlStream);
XmlNodeList stations = xml.SelectNodes("//Station");
foreach (XmlNode station in stations)
{
var code = station.SelectSingleNode("Code").InnerXml;
var type = station.SelectSingleNode("Type").InnerXml;
var longName = station.SelectSingleNode("Names/Long").InnerXml;
var blah = "you should get the point by now";
}
NOTE: If your xmlStream variable is a String, rather than a Stream, use xml.LoadXml(xmlStream); for line 2, instead of xml.Load(xmlStream). If this is the case, I would also encourage you to name your variable to be more accurately descriptive of the object you're working with (aka. xmlString).
This will give you all the values of "Long" for every Station element.
var xml = XDocument.Parse(xmlStream);
var longStationNames = xml.Elements("Long").Select(e => e.Value);
I have an XML file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<PathMasks>
<Mask desc="Masks_X1">
<config id="01" mask="88" />
<config id="03" mask="80" />
<config id="51" mask="85" />
</Mask>
<Mask desc="Masks_X2">
<config id="70" mask="1" />
<config id="73" mask="6" />
</Mask>
<Types>
<path id="01" desc="TC->PP1" />
<path id="02" desc="TC->PP2" />
<path id="03" desc="TC->PPn" />
</Types>
</PathMasks>
How to parse the file and get all the data of Mask_X1 as following:
id value
=====
01, 88
03, 80
51, 85
The .NET framework I am using is 2.0
As you're working with .Net 2.0 you won't have Linq and will therefore need to use XPath, this sample should help you out.
XmlDocument doc = new XmlDocument();
doc.Load(pathToXmlDoc);
XmlNode node = doc.SelectSingleNode("/PathMasks/Mask[#desc='Masks_X1']");
foreach (XmlNode config in node)
{
Console.WriteLine("{0}\t{1}",
config.Attributes["id"].Value,
config.Attributes["mask"].Value);
}
Using XmlDocument (slower, larger memory footprint, read/write, works the same way XML DOMs everywhere work):
XmlDocument d = new XmlDocument();
d.Load(filename);
string xpath = "/PathMasks/Mask[#desc='Mask_X1']/config"
foreach (XmlElement elm in d.SelectNodes(xpath))
{
Console.WriteLine(elm.GetAttribute("id"), elm.GetAttribute("desc"));
}
Using XPathDocument (faster, smaller memory footprint, read-only, weird API):
XPathDocument d = new XPathDocument(filename);
string xpath = "/PathMasks/Mask[#desc='Mask_X1']/config"
XPathNodeIterator iter = d.CreateNavigator().Select(xpath);
while (iter.MoveNext())
{
Console.WriteLine(iter.Current.GetAttribute("id"), iter.Current.GetAttribute("desc'));
}
I'm sure there's a perfectly good reason why there isn't a method of XPathNavigator that returns an IEnumerable<XPathNavigator> so that you can iterate over the results of an XPath query like a normal person, but I haven't been able to work it out.
Using Linq to XML :
XDocument doc = XDocument.Load(filename);
var query = from mask in doc.Root.Elements("Mask")
where mask.Attribute("desc").Value == "Masks_X1"
from config in mask.Elements("config")
select new
{
id = config.Attribute("id").Value,
value = config.Attribute("mask").Value
};
foreach(var mask in query)
{
Console.WriteLine("{0}\t{1}", mask.id, mask.value);
}
Use XDocument and query into it with Linq to XML
XDocument doc = XDocument.Load("file.xml");
var linqtoxml = from node in document.Descendants("Mask")
where (string)node.Attribute("desc").Value == "Masks_X1"
select node;
foreach (var mask in linqtoxml)
{
// pull data out of here into a structure of your choosing
}