I need a list of all the Attribute ID(the value) of Descendants(Frame) that have an Attribute SecondFeature (Descendants-ObjectClass) that equal Vehicle.
(there is node that have 1 "object", other 2/3 time and other not at all)
this is a part of the code:
<?xml version="1.0" encoding="utf-8" ?>
- <Frame ID="120">
<PTZData Zoom="1.000" />
- <Object ID="5">
<ObjectClass SecondFeature="vehicle" />
</Object>
</Frame>
You can do it with following XPath expression:
var xml = // your XML string here
var doc = XDocument.Parse(xml);
var frameIds = doc.Root.XPathSelectElements(
"//Frame[./Object/ObjectClass[#SecondFeature ='Vehicle']]")
.Select(n => n.Attribute("ID").Value);
Naturally, if your Frame nodes can be present without ID attributes, you'll need extra null checks in .Select.
Alternatively, non-xpath appraoch (but this is IMHO less readable and calls for even more caution):
var frameIds = doc
.Descendants("ObjectClass")
.Where(n => n.Attribute("SecondFeature").Value == "Vehicle")
.Select(n => n.Parent.Parent.Attribute("ID").Value);
Related
I'm trying to delete a parent from a element in XML.
My XML:
<root>
<Element1 ManagementID="10" />
<Users>
<UserID ManagementID="10">
<Identification IDValue="1" />
<!-- More elements Here -->
</UserID>
</Users>
<!-- More Users elements Here -->
I find my user my its IDValue:
XElement user = (from el in document.Root.Elements("Users").Elements("UserID ").Elements("Identification")
where (string)el.Attribute("IDValue") == myID
select el).FirstOrDefault();
Now, I would like to remove all the user.Parent.Parent
I mean delete the element:
<Users>
<UserID ManagementID="10">
<Identification IDValue="1" />
<!-- More elements Here -->
</UserID>
</Users>
** I'll have many Users elements, that's why first I look for the identification IDValue
I found the solution for who needs it:
I already had the node from my linq so
user.Parent.Parent.Remove()
var user = document.Root
.XPathSelectElements("//UserId")
.FirstOrDefault(userId => userId.Element("Identification").Attribute(XName.Get("IDValue")).Value == myID);
Try this :
List<XElement> users = document.Descendants("Users")
.Where(user => user.Elements("Identification")
.Where(el => (string)el.Attribute("IDValue") != myID)
.Any()).ToList();
XElement element1 = document.Descendants("Element1").FirstOrDefault();
element1.ReplaceNodes(users);
Is there a way we can sort xmlnodes based on attribute values? The point is that every child node has a different name, despite it, I want to sort them by attribute.
E.g.
<Doc>
<mar_03 data="03">
<Mattina_Turno_1 />
</mar_03>
<dom_01 data="01">
<Mattina_Turno_1 />
</dom_01>
<mer_04 data="04">
<Mattina_Turno_1 />
<Mattina_Turno_2 />
</mer_04>
</Doc>
Should become
<Doc>
<dom_01 data="01">
<Mattina_Turno_1 />
</dom_01>
<mar_03 data="03">
<Mattina_Turno_1 />
</mar_03>
<mer_04 data="04">
<Mattina_Turno_1 />
<Mattina_Turno_2 />
</mer_04> </Doc>
How can I do it? After sorting obviously I want to overwrite the file.
This answer does not fix my problem since i can not define the node "item" since every my nodes are named differently.
Thanks, and please do not mark it as duplicate, because it is not!
Please try,
XDocument xdoc = XDocument.Load("File.xml");
var result = xdoc.Element("Doc")
.Elements()
.OrderBy(s => (int)s.Attribute("data"));
string xmlOutPut = string.Empty;
result.ToList().ForEach(a =>
{
xmlOutPut += a;
});
Where data and Doc is the parent element is your attribute according to your example. File.xml is your xml file name. You will get the sorted output in 'xmlOutPut'
or everything in a single Linq query,
XDocument xdoc = XDocument.Load("XMLFile2.xml");
string xmlOutPut = string.Empty;
xdoc.Element("Doc")
.Elements()
.OrderBy(s => (int)s.Attribute("data"))
.ToList().ForEach(a =>
{
xmlOutPut += a;
});
Sorting
XDocument xDoc = XDocument.Load("FileName.xml");
var res = xDoc.Element("Doc")
.Elements()
.OrderByDescending(c => (int) c.Attribute("data"));
Then to save it:
XDocument doc = new XDocument(new XElement("Doc", res));
doc.Save("FileName.xml");
flow.Name definitely equals the 'name' of one of the flows in the flowData XDocument.
XElement rootelem = flowData.Root.Element("flows");
after the above line the rootelem contains the flows element and it's children as expected BUT the below line throws a null reference exception, why?
flowData.Root.Element(flow.Name).Remove();
flowData is declared as an XDocument and looks like so:
<?xml version="1.0" encoding="UTF-8"?>
-<D53ESB>
-<comms>
<diagnosticemails sender="eventlog"/>
</comms>
-<globalparams>
<!-- some comments... -->
</globalparams>
-<flows>
-<flow webserviceonly="false" stoponerror="true" name="testFlow">
-<action name="t1">
<schedule firsttime="01/01/2014 14:10:00" every="600000"/>
-<adapter name="GetXml">
<param name="url" value="http://xml.betfred.com/Football-Championship.xml"/>
</adapter>
</action>
</flow>
...more flows
</flows>
</D53ESB>
These two lines return null too:
var xelem2 = flowData.Root.Element(flow.Name);
var xelem3 = flowData.Root.Element("flows").Element(flow.Name);
And these two return empty sets:
var keepgoing = new XDocument(rootelem.Descendants(flow.Name));
var idk = new XDocument(flowData.Descendants(flow.Name));
XElement.Element method expects an element name, not an attribute value. It doesn't know which attribute value is the name of your element....
You should try:
flowData.Root.Element("flows")
.Elements("flow")
.Where(f => (string)f.Attribute("name") == flow.Name);
<?xml version="1.0" encoding="UTF-8"?>
<meta>
<field type="xs-string" name="AssetId">TF00000002</field>
<field type="xs-string" name="Title">TitleOfAsset</field>
</meta>
I have this XML loaded in to a XDocument using the function
XDocument doc = XDocument.Parse(xmlData)
However, I want to be able to retrieve the text fields "TF00000002" and "TitleOfAsset" ... How do I go about doing this?
templateMetaData.assetID = doc
.Descendants()
.Where(p => p.Name.LocalName == "AssetId")
.ToString();
returns:
System.Linq.Enumerable+WhereEnumerableIterator`1[System.Xml.Linq.XElement]
Can anyone shine a light on this?
In your query, you are calling ToString on an IEnumerable<XElement> which will never give you the expected result, instead look for field elements under your Root and get their value:
var values = doc.Root
.Elements("field")
.Select(element => (string)element);
If you want to access your values using the name attribute you can use Dictionary:
var values = doc.Root
.Elements("field")
.ToDictionary(x => (string)x.Attribute("name"), x => (string)x);
Then you can access the value of AssetId:
var id = values["AssetId"];
I read through this post.
I have this XML:
<?xml version="1.0" encoding="utf-8" ?>
<Export version="" srcSys="" dstSys="" srcDatabase="" timeStamp="">
</Export>
This is what i tried, but with no luck:
var xml = XElement.Parse(BuyingModule.Properties.Resources.Export);
Func<XElement, string, string> GetAttribute = (e, property) => e.Elements("property").Where(p => p.Attribute("name").Value == property).Single().Value;
var query = from record in xml.Elements("Export")
select record;
var prop = GetAttribute(query.FirstOrDefault(), "version");
How do i access to properties of the "Export" Node?
I need to set those properties
The Export element doesn't have a properties element, which is what your GetAttribute method is trying to find.
My guess is you actually want:
var element = xml.Element("Export"); // Just get the first element
var version = (string) element.Attribute("version");
It's not clear to me why you've used a query expression and a delegate here - it's just things more complicated than you need. But Attribute(XName) is probably what you were missing...