Let's say I have an xml string:
<?xml version="1.0" encoding="UTF-8"?>
<Return version="1.0">
<File>1</File>
<URL>2</URL>
<SourceUUID>1191CF90-5A32-4D29-9F90-24B2EXXXXXX0</SourceUUID>
</Return>
and I want to extract the value of SourceUUID, how?
I tried:
XDocument doc = XDocument.Parse(xmlString);
foreach (XElement element in doc.Descendants("SourceUUID"))
{
Console.WriteLine(element);
}
If all you want is the content of the SourceUUID element, and there's only going to be 1 in the XML, you can do this:
XDocument doc = XDocument.Parse(xmlString);
var value = doc.Descendants("SourceUUID").SingleOrDefault()?.Value;
If there are going to be more than one, you can do this:
var values = doc.Descendants("SourceUUID").Select(x => x.Value);
This gives you an enumerable of strings that are the text values of the elements.
Related
I,ve searched a bit, but didn't find anythings that I think is right for an answer, I'm using a XDocument to load my xml, but I'm having some trouble to transform it into an array
<?xml version="1.0" encoding="UTF-8"?>
<document>
<sNone>
<October>3.21</October>
<November>-5.41</November>
<December>-15.81</December>
<January>-21.69</January>
<February>-21.70</February>
<March>-12.60</March>
<April>-6.41</April>
<May>-0.06</May>
<June>5.42</June>
<July>13.32</July>
<August>14.12</August>
<September>7.55</September>
</sNone>
<sLichen>
<October>1.99</October>
...
</sLichen>
</document>
I'm loading my XML like so
XDocument doc = XDocument.Parse();
but I'm confused on how to return a 1D array because I have multiple descendant.
EDIT
What I'm aiming to get is an array like this
{3.21, -5.41, -15.81, -21.69, -21.70, -12.60, -6.41, -0.06, 5.42, 13.32, 14.12, 7.55}
This should do the trick :
var doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?....";
XDocument xdoc = XDocument.Parse(doc);
var items = xdoc.Root.Elements("sNone").Descendants().Select(d => d.Value).ToArray();
Console.WriteLine(items);
Or if you want decimals :
var items2 = xdoc.Root.Elements("sNone").Descendants().Select(d => decimal.Parse(d.Value)).ToArray();
Hope this helps.
I've been coding a program that stores employee data using XDocument:
<!-- School Employee Data -->
<SchoolData storeName="mikveIsrael" location="mikve">
<employee id="1">
<personalInfo>
<name>Ilan Berlinbluv</name>
<zip>58505</zip>
</personalInfo>
<employeeInfo>
<salary>5000</salary>
<id>1</id>
</employeeInfo>
</employee>
<employee id="2">...</employee>
</SchoolData>
I want my program to read every employee id attrib, but I don't know how to do so. Instead, I tried doing this:
var ids = from idz in doc.Descendants("SchoolData")
select new
{
id1 = idz.Element("employee").Attribute("id").Value
};
where doc is the XDocument var. It returns just the first one, but I want it to return an array or List<string>, I just don't know how to iterate through all the same-named employee elements.
XDocument doc = XDocument.Parse(xml);
List<string> ids = doc.Descendants("employee")
.Select(e => e.Attribute("id").Value)
.ToList();
This may helps:
var xDoc = XDocument.Load(path);
var result = xDoc.Descendants("employee")
.SelectMany(i => i.Attribute("id").Value)
.ToList();
I have an XML doc which looks roughly like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Multiple xmlns:ns2="someNs2" xmlns="someGenericNs" xmlns:ns4="someNs4" xmlns:ns3="someNs3">
<Single>
<Id>60000</Id>
<Type>Activate</Type>
<Payload>
<ns3:Activation>
<ns3:Parent>
<ns3:TypeId>113</ns3:TypeId>
<ns3:TypeName>TestApplication</ns3:TypeName>
</ns3:Parent>
<ns3:Children>
<ns3:Child>
<ns3:Key>someKey</ns3:Key>
<ns3:ChildTypeName>BadAppType1</ns3:ChildTypeName>
</ns3:Child>
<ns3:Child>
<ns3:Key>someOtherKey</ns3:Key>
<ns3:ChildTypeName>GoodAppType1</ns3:ChildTypeName>
</ns3:Child>
</ns3:Children>
</ns3:Activation>
</Payload>
</Single>
</Multiple>
If the file contains multiple "Child" nodes i would like to split it into more files, 1 file for each existing child node. Something like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Multiple xmlns:ns2="someNs2" xmlns="someGenericNs" xmlns:ns4="someNs4" xmlns:ns3="someNs3">
<Single>
<Id>60000</Id>
<Type>Activate</Type>
<Payload>
<ns3:Activation>
<ns3:Parent>
<ns3:TypeId>113</ns3:TypeId>
<ns3:TypeName>TestApplication</ns3:TypeName>
</ns3:Parent>
<ns3:Children>
<ns3:Child>
<ns3:Key>someOtherKey</ns3:Key>
<ns3:ChildTypeName>GoodAppType2</ns3:ChildTypeName>
</ns3:Child>
</ns3:Children>
</ns3:Activation>
</Payload>
</Single>
</Multiple>
And then a new XmlDoc containing the other "Child" node. Can this be achieved through LINQ?
My code so far is:
private bool HasMoreThanOneChild(string xml) {
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
if (doc.GetElementsByTagName("ns3:Child").Count > 1)
{
return true;
}
return false;
}
public List<string> DoSomething(XmlDocument doc){
if(HasMoreThanOneChild(doc.InnerXml))
return Split(doc);
}
I returned a List there because I'm more interested in the "InnerXML" once the doc is split. But I am at a loss of how to implement this split, if it is possible.
XNamespace ns="someNs3";
//get all Child elements
var childElements=doc.Descendants().Elements(ns+"Child").ToList();
//remove those child elements
doc.Descendants().Elements(ns+"Child").ToList().ForEach(x=>x.Remove());
int i=1;
foreach(var child in childElements)
{
//add that child to children element
doc.Descendants().Elements(ns+"Children").First().Add(child);
//save it to new file!
doc.Save("file"+i+".xml");
doc.Descendants().Elements(ns+"Child").ToList().ForEach(x=>x.Remove());
i++;
}
I want to create a dictionary for the following xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<groups>
<group>
<data>Open</data>
<aggregation>5</aggregation>
</group>
</groups>
I want my dictionary to get the values as:
Open,5
Please note that 'Open' is fetched from <data>Open</data> and '5' is fetched from <aggregation>5</aggregation>.
My current code is as follows:
foreach (XmlNode group in Bugsagg)
{
XmlNode data = group.SelectSingleNode(".//data");
XmlNode aggregate = group.SelectSingleNode(".//aggregation");
if (Dict_Aggregate.ContainsKey(data.InnerText))
{
Dict_Aggregate[data.InnerText]++;
}
else
{
Dict_Aggregate.Add(data.InnerText, 1);
}
I am not getting the desired response. Please suggest where i am doing wrong.Thanks
Use XElement and LINQ to XML.
You should add
using System.Xml;
using System.Xml.Linq;
on top of your code. Then use the following
string xml = #"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><groups><group><data>Open</data><aggregation>5</aggregation></group></groups>";
XElement xe = XElement.Parse(xml);
Dictionary<string,string> d =
xe.Elements("group")
.ToDictionary
(
x=>(string)x.Element("data"), //Key Selector
z=>(string)z.Element("aggregation")//Value Selector
);
Some people might also suggest to use an XDocument as you provide a fully qualified xml with declaration etc:
XDocument xd = XDocument.Parse(xml);
Dictionary<string,string> d =
xd.Root.Elements("group")
.ToDictionary
(
x=>(string)x.Element("data"), //Key Selector
z=>(string)z.Element("aggregation")//Value Selector
);
I don't how to extract the values from XML document, and am looking for some help as I'm new to C#
I am using XmlDocument and then XmlNodeList for fetching the particular XML document
Here is my code
XmlNodeList XMLList = doc.SelectNodes("/response/result/doc");
And my XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<result>
<doc>
<long name="LoadID">494</long>
<long name="EventID">5557</long>
<str name="XMLData"><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>tblQM2222Components</SubType><IntegerValue title="ComponentID">11111</IntegerValue></str></doc>
<doc>
<long name="LoadID">774</long>
<long name="EventID">5558</long>
<str name="XMLData"><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>tblQM2222Components</SubType><IntegerValue title="ComponentID">11111</IntegerValue></str></doc>
</result>
</response>
In this i have to fetch every the XMLData data that is under every doc tag and i have to fetch last doc tag EventID.
var xml = XDocument.Parse(xmlString);
var docs = xml.Root.Elements("doc");
var lastDocEventID = docs.Last()
.Elements("long")
.First(l => (string)l.Attribute("name") == "EventID")
.Value;
Console.WriteLine ("Last doc EventId: " +lastDocEventID);
foreach (var doc in docs)
{
Console.WriteLine (doc.Element("str").Element("TransactionDate").Value);
}
prints:
Last doc EventId: 5558
2014-05-28T14:17:31.2186777-06:00
2014-05-28T14:17:31.2186777-06:00
You can use two XPath expressions to select the nodes you want. To answer each part of your question in turn:
To select all of the XMLData nodes:
XmlNodeList XMLList
= doc.SelectNodes("/response/result/doc/str[#name='XMLData']");
To select the last EventId:
XmlNode lastEventIdNode =
doc.SelectSingleNode("/response/result/doc[position() =
last()]/long[#name='EventID']");
If not all doc nodes are guaranteed to have an event id child node, then you can simply:
XmlNodeList eventIdNodes =
doc.SelectNodes("/response/result/doc[long[#name='EventID']]");
XmlNode lastNode = eventIdNodes[eventIdNodes.Count - 1];
That should give you what you've asked for.
Update;
If you want the XML data inside each strXml element, you can use the InnerXml property:
XmlNodeList xmlList
= doc.SelectNodes("/response/result/doc/str[#name='XMLData']");
foreach(XmlNode xmlStrNode in xmlList)
{
string xmlInner = xmlStrNode.InnerXml;
}
There's one result tag short in your xml.
Try using this. It's cleaner too imho
XmlNodeList docs = doc.SelectSingleNode("response").SelectSingleNode("result").SelectNodes("doc");
Then you can use a combination of SelectSingleNode, InnerText, Value to get the data from each XmlNode in your list.
For example if you want the EventID from the first doc tag:
int eventID = int.Parse(docs[0].SelectSingleNode("long[#name='EventID']").InnerText);