Click here to Skip to main content
15,887,375 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Dear all,

Please forgive me if my terminology isn't accurate, it's a new field for me. :)
I have implemented a class in VB which is serialized to xml (actually the xml-file will be deserialized to the class, however)

So the XML:
XML
<Universe>
<Jedi>
<Person Name="Yoda" Age="1000"/>
</Jedi>
</Universe>

resulting Class:
VB
<XmlRoot ("Universe"), Serializable()> _
Public Class Universe
<XmlArray("Jedi")> _
<XmlArrayItem("Person")>
Public Persons as list(Of Person)
End Class

Public Class Person
<XmlAttributeAttribute ("Name")> _ 
Public Name as string
<XmlAttributeAttribute ("Age")> _ 
Public Age as String
End Class

So far so good...
Now I have a situation, where an unknown amount of additional Attributes needed to be added to some "Persons", just like

XML
<Person Name="Obi Van" Age="2000" isMaster="yes" isAlive="no">
<Person Name="Luke" Age="300" isMaster="no">


So my idea was to add a Dictionary(Of String, String) to my Person Class to collect all the "is..."-Attributes of the Xelement Person into.

First of it, I cant use a Dictionary at this point (as the debugging pointed to me...) and I have no idea how to collect all attributes of an XElement to a List or some for further processing.

XML
Public Class Person
<XmlAttributeAttribute ("Name")> _
Public Name as string
<XmlAttributeAttribute ("Age")> _
Public Age as String

<???XmlattributesOfElement???>
public myAttributes as [Attributes of Element startwith "is"]
End Class


Anyway, I don't really see, how to get the Xelement at all... (althought I had to implement a Function with a different reader, or so.... )

Actually, if there is a better way to handle this at all, I was thankful for any alternatives!

Any hints are appreciated!
Thanks in advance,
Daniel
Posted

You will have to implement IXmlSerializable[^] in your Person class and serialize/deserialize yourself.

Here is an article that shows how to implement it: How to Implement IXmlSerializable Correctly[^]

Its not hard, the XmlReader gives you access to the attributes, but you have to move between elements yourself, and you also have to serialize yourself (so the attributes you put on your properties become meaningless).
 
Share this answer
 
Comments
Daniel Balogh 29-Jan-14 6:18am    
Hello,
reading the links, I haven't see any approach to handle the attributes flexible - at least not in combination with class-serialization. If I stick on my Attribute-thing, I would need to implement a second reader that reads the attributes of my serialized "Person" and passing the Name Att of the Person....
Thank you for taking time, it seems, there is no "single-liner" for this case.
It seems to me, I need to add a subclass with additional Elements to my Person Class...
BR,
Daniel
Dictionaries of .NET are not serialize-able, so you have to implement it yourself...
C#
public class Property<K, V>
{
    public K Key
    {
        get;
        set;
    }

    public V Value
    {
        get;
        set;
    }
}
public class Person
{
    public Person ( )
    {
        Properties = new List<Property<string, object>>( );
    }

    public string Name
    {
        get;
        set;
    }

    [XmlElement( "Propery" )]
    public List<Property<string, object>> Properties
    {
        get;
        set;
    }
}

C#
oPerson.Name = "Peter";
oPerson.Properties.Add( new Property<string, object>( )
{
    Key = "Age",
    Value = 42
} );
oPerson.Properties.Add( new Property<string, object>( )
{
    Key = "Gender",
    Value = "male"
} );

XML
<?xml version="1.0" ?>
<Person>
  <Name>Peter</Name>
  <Propery>
    <Key>Age</Key>
    <Value>42</Value>
  </Propery>
  <Propery>
    <Key>Gender</Key>
    <Value>male</Value>
  </Propery>
</Person>

This will give you a list of key-value pairs that can be serialize...
 
Share this answer
 
v2
Comments
Daniel Balogh 29-Jan-14 5:39am    
Hi, thank you for taking time. Actually, your description targets Xelements, which already work, so his doesn't really answer the question.
I meant to collect Attributes of an Element in some kind of container (I understood, that dictionaries are not an option) for further processing.
BR,
D
Kornfeld Eliyahu Peter 29-Jan-14 5:55am    
Did you see the <Property> part?
Those created out of a list (container) of arbitrary values assigned to keys...
It sounds me exactly what you asked for...
(added code of how the serilized object created)
Daniel Balogh 29-Jan-14 6:10am    
Hello! Yes, I've seen it, but still, this way targets Elements, not Attributes of an Element.
I decided to use Attributes for better readability by man :), did not want to have too much tags in the XML-File. :-)
If I understand it right, your code shows a way to create a dictionary-like structure, and I'm pretty sure it will help me in some future scenarios.
In my current situation I get an XML-file (format provided by me) and deserialize it to my class. I'm not fixed on a dictionary, any kind of data container was OK, holding all the attributes of one certain Element for further processing.
So I get the XML-file with the given Element Structure (= my Class) but the Attributes of the elements could vary. On the Class side there were a [Container] holding all Attributes to process. Background is an Autocad-Plugin, I get the BlockReference information and have to match Blockattributes (key-value) - which can vary - on insert in the drawing... If I give a Namepattern to the XMLAtts (prefix...) I could easily filter them from a list (key-value) :)
Sorry if my question wasn't clear.
Kornfeld Eliyahu Peter 29-Jan-14 6:22am    
<Propery Key="Age" Value="42" />
<Propery Key="Gender" Value="male" />
This for suits you better?
Daniel Balogh 29-Jan-14 6:30am    
As written in the orig post the goal was:
<Person Name="Peter" Age="42" Gender="male" />
<Person Name="Daniel" Age="36" Gender="male" hasPet="yes" hasCoffee="no" />

with your solution this would be (altered to Name as Att - since this is always there):
<Person Name="Peter">
<Propery Key="Age" Value="42" />
<Propery Key="Gender" Value="male" />
</Person>
<Person Name="Daniel">
<Propery Key="Age" Value="36" />
<Propery Key="Gender" Value="male" />
<Propery Key="hasPet" Value="yes" />
<Propery Key="hasCoffee" Value="no" />
</Person>

Actually, I see I have not other choice than this, but this is less readable by man in my eyes...
BR,
Daniel

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900