I'm try to understandin Linq to XML and I've this file XML:
<?xml version="1.0" encoding="utf-8"?>
<Headers xmlns="http://tempuri.org/GridLayerSchema.xsd">
<Header>
<Name>Layer0</Name>
<Fields FieldID="FieldID0" FieldName="FieldNameAll" FieldPosition="0" FieldPositionStart="0" FieldLenght="254" FieldEnable="true" />
</Header>
<Header>
<Name>Layer1</Name>
<Fields FieldID="FieldID0" FieldName="JetPosition" FieldPosition="0" FieldPositionStart="0" FieldLenght="14" FieldEnable="true" />
<Fields FieldID="FieldID1" FieldName="Owner" FieldPosition="1" FieldPositionStart="14" FieldLenght="14" FieldEnable="true" />
<Fields FieldID="FieldID2" FieldName="Item" FieldPosition="2" FieldPositionStart="28" FieldLenght="3" FieldEnable="true" />
</Header>
</Headers>
I'll try to take all elements with a linq query for making a VB.net class, somethink like this:
Class Field:
Public Class Field
Public Property FieldID1 As String
Public Property FieldName As String
Public Property FieldPosition As Integer
Public Property FieldPositionStart As Integer
Public Property FieldLenght As Integer
Public Property FieldEnable As Boolean
End Class
Then the Header class:
Public Class Header : Inherits Field
Public Property Name As String
End Class
In this one I'va a function for making a Headers collection:
Public Shared Function HeadersLoader() As Headers
Dim HeadersCollection As New Headers
Dim ns As XNamespace = "http://tempuri.org/GridLayerSchema.xsd"
Dim xdoc As XDocument = XDocument.Load(My.Application.Info.DirectoryPath & "\Layers\Headers.xml")
Dim HeadersQuery = From Header In xdoc.Root.Elements(ns + "Header")
Select Header
For Each e In HeadersQuery
Dim _mHeader As New Header
With _mHeader
.Name = e.Value.ToString
End With
HeadersCollection.Add(_mHeader)
Next
Return HeadersCollection
End Function
Now I've two questions:
Why I've the Header's name in Value property and not in Name property (in name property I've all the namespace and the header tag, but not the name: {http://tempuri.org/GridLayerSchema.xsd}Header )
How can I read all fields of the current Header?I need a nested query? I'll thought, with my query, to find all but seems not so, I can read only the first node.
You're being confused by the fact that the Value
property on XElement
will concatenate all the text nodes within an element, including within descendants. That happens to be getting the text value of the Name
child element, because that's the only element you've got with any text. It would be better to write:
With _mHeader
.Name = e.Element(ns + "Name").Value
That way you're explicitly asking for the text within the <Name>
child element.
Now your class design is a bit messed up because you're saying that a header is a field, rather than that it has a list of fields. I think you should have something like:
Public Class Header
Public Property Name As String
Public Property Fields As List(Of Field)
End Class
(possibly with some initialization). I would then change your LINQ query to create the instances of Header
within the Select
clause. I'm not going to attempt the VB, but in C# I'd have something like:
var headers = xdoc.Root.Elements(ns + "Header")
.Select(header => new Header
{
Name = header.Element("Name").Value,
Fields = header.Elements("Fields")
.Select(field => new Field
{
FieldID1 = field.Element("FieldID)".Value,
// etc
})
.ToList();
});
You might want to add static FromXElement
methods to Header
and Field
(where Header.FromXElement
would use Field.FromXElement
) to make this all a bit simpler.
See more on this question at Stackoverflow