I am having a lot of trouble translating examples I am finding into use with XML.
Starting with this (a very cut down version of the whole XML file)
<?xml version="1.0" encoding="UTF-8"?>
<MetadataSets>
<MetadataSet MetadataSetID="999_never" >
<MetadataSetItem>
<TagName>NeverSeen</TagName>
<ItemSeq>10</ItemSeq>
</MetadataSetItem>
<MetadataSetItem>
<TagName>AlsoNeverSeen</TagName>
<ItemSeq>20</ItemSeq>
</MetadataSetItem>
</MetadataSet>
</MetadataSets>
What I am trying to do is create an ordered list of 2 fields which, eventually, I hope to return as a List of Tuples
'NeverSeen' 10
'AlsoNeverSeen' 20
The following are a list of several approaches I have tried - mostly included to show I have made an effort before calling for help.
I would love some help to put me on the right trail for this specific problem but also does anybody have a suggestion for a decent, non trivial, tutorial on LINQ for XML.
I should say I am coming from a Database background; 30 seconds in SQL - 5 days and counting for XML and LINQ.
I am also getting confused with different approaches - and probably inadvertently mixing them eg those that use 'from'
var schema3 = from el in XDoc.Elements("MetadataDomain")
where (String)el.Attribute("DomainUUID") == pDomainUUID
select (el);
then iterate the el
even if there is only one.
Or those that don't use 'from' but use '.'
var schema4 = XDoc.Elements("MetadataDomain")
.Where(sch => (String)sch.Attribute("DomainUUID") == pDomainUUID)
.Select(sch => (String)sch.Element("SchemaName").Value);
then you still have to iterate the result even if there is only one.
I was warming to XPath eg
string schema5 = root.XPathSelectElement($"MetadataSets/MetadataDomain[@DomainUUID='{pDomainUUID}']").Element("SchemaName").Value;
But went off that because it's all on one line so when it crashes there is no way to debug anything. And pretty much anything you type in will compile.
And how do I select 2 'fields', for example some say to select 2 'fields' use anonymous types eg
select new { car.Make, car.VIN}
when I try that with XML
where (String)el.Attribute("MetadataSetID") == pMetadataSetID
select new { el.Element("TagName").Value, el.Element("ItemSeq").Value } ;
I get a compile error
Error CS0833: an anonymous type cannot have multiple properties with the same name
Seems the compiler cannot tell these apart and I don't know how to alias them.
Thanks JC
As usual I have shot myself in the foot by only showing a snippet of information In fact the data is normalised into at least 2 'tables' that are represented in XML The SchemaName(s) are perhaps subject area views. The MetadataSetID(s) give the subset and order of these Metadata items for a specific user audience.
The resultant data that has to be returned way up tree is the intersection of these for ONE SchemaName and ONE MetadataSetID As you can see even in this early stage there are many 'columns' / Properties involved. Way more than a dictionary can cope with for example.
Following the clarification Yong Shun yesterday I got furthur but then got stuck applying the filter for MetadataSetID it being 2 levels up from the Tags I was looking for. Having just clarified my thoughts on the end-state I will have a crack at the techniques decius suggested
<!-- semi denormalised - what a database would look like
SchemaName TagName TagLabel TagType TagSize TagRepetative TagDelimiter
EHGS-Standard FamilyName Family Name string 255 true ;
EHGS-Standard BusinessName Business Name string 255 true ;
EHGS-Standard What What (Categories) string true ;
EHGS-Standard Where Where string true ;
EHGS-Standard When When string true ;
EHGS-Standard Contributor Contributor string true ;
EHGS-Standard Comments Comments string false ;
EHGS-Standard Title Title string true ;
EHGS-Standard Copyright Copyright string true ;
EHGS-Standard Subject Subject string true ;
EHGS-Standard Authors Authors string true ;
EHGS-Standard DocumentID Document ID string false ;
testPretendSchema Creator Creator string 255 true ;
testPretendSchema Reader Last Reader string 255 true ,
testPretendSchema What What (whatever) string true ;
MetadataSetID TagName ItemSeq TagScope
001_basic DocumentID 120 Restricted
001_basic FamilyName 10
001_basic BusinessName 20
001_basic What 30
001_basic Where 40
001_basic When 50
001_basic Comments 60
001_basic Title 70
001_basic Contributor 80
001_basic Copyright 90
001_basic Subject 100
001_basic Authors 110
999_neverTest NeverSeen 10
999_neverTest AlsoNeverSeen 20
-->
select new { TagName = el.Element("TagName").Value, ItemSeq = el.Element("ItemSeq").Value }