I want to make an xml file (using c# with XmlWriter) and I need to have 2 or more Elements with different attribute Values. for example:
<MyGuest Type = "Adult" Number = "2">
<MyGuest Type = "Child" Number = "1" Age = "12">
is this something that can be done with XmlWriter? when I use
writer.WriteAttributeString("Number","2");
writer.WriteAttributeString("Type","Aduld");
writer.WriteAttributeString("Age","12");
writer.WriteAttributeString("Number","1");
writer.WriteAttributeString("Type","Child");
I get en exception that says "Additional information: 'Number' is a duplicate attribute name."
Any advice please?
So it seems that the question is asked wrongly. I want to add different values to that attributes in the xml file so it would look like this:
<Guests>
<MyGuest Type = "Adult" Number = "2">
<MyGuest Type = "Child" Number = "1" Age = "12">
</Guests>
any advice please?
Thank you for your time!
I think something like this is what you want:
writer.WriteStartElement("MyGuest");
writer.WriteAttributeString("Type","Adult");
writer.WriteAttributeString("Number","2");
writer.WriteEndElement();
writer.WriteStartElement("MyGuest");
writer.WriteAttributeString("Type","Child");
writer.WriteAttributeString("Age","12");
writer.WriteAttributeString("Number","2");
writer.WriteEndElement();
But generally it would be better to know more about your usecase. Are Child and Adult classes you want to serialize? Then I would propose you that the classes should implement IXmlSerializable. This forces the types to implement Read and WriteXml methods. In these methods you can put the logic and call them from outside. This gives you more loose coupling and also more flexibillity if you add new types. Then you dont have to change your "one-method-serialization" every time. You would only implement the new behaviour in the new class it belongs.
If you go this way, you could make also a abstract base class "Guest" that has the property "Number". In the base Read and WriteXml you would de/serialize just this property and you dont have to repeat yourself in every additional "guest type" like child or adult...
You can't do that: An attribute name cannot be used more than once in the same element.
Whatever way you use to accomplish your goal - the result is not valid XML.
Well-formed XML cannot contain duplicate attributes on an element.
From the xml spec section 3.1:
Well-formedness constraint: Unique Att Spec
An attribute name MUST NOT appear more than once in the same start-tag
or empty-element tag.
http://www.w3.org/TR/REC-xml/#sec-logical-struct
Related
I'm implementing a custom XmlTextWriter and I'd like to omit any elements with a particular name that contain no attributes. I've gotten as far as being able to prevent the element from being written by overriding WriteStartElement and WriteEndElement, but is there a way to know at WriteStartElement or at any other useful point whether or not the element has any attributes?
No. However you can postpone writing of the element and attributes (put them in a field) until you get to the next element/comment/etc. Then decide whether you want to write them or not.
Can we have a required XmlAttribute that does not allow null value?
I want to have something like IsRequired = true in XmlAttribute. Can it be done? I know that there is a 'use="required"' for XmlAttribute, but we can't set its value, can we? Is there any trick to serve this purpose?
I'm still a little confused by what you're trying to do, so i'm assuming that you wish to validate your input xml before attempting to use it in your webservice. In your case your XML needs to have a specific attribute.
To do something like that I typically create an XSD against the XML that should be received and use that to validate it against the XML. The XSD will contain the details that the XML must contain a certain node / attribute. You can use visual studio XSD editor to configure these items.
This topic should help you with the validation code once you're XSD is created:
Validating an XML against referenced XSD in C#
Greetings all,
I have a list of "Types" meeting a certain critera that I obtained through reflection. Each of the types is a different feature that the user will potentially choose at runtime. If I add more subclasses later, this dynamic implementation would save my having to remember to update the user control is the idea here.
The list of types is nice, but it'd be nice to display something more meaningful than the Name as it's written in code. For example, instead of "RacingBikeDesigner", I'd like to display "Racing Bike Designer", and maybe even display other properties associated with that type like "Description" so that the user knows what that particular choice does.
So I guess the question is, given a Type, how can I provide a more meaningful representation to the user? Could I maybe add a static field to each subclass and call that from the Type, or could I perhaps use a type converter somehow?
The user control (ListBox, ComboBox, etc) is bound to the return value below, but it's not user-friendly:
List<string> LeftHandedUserChoices = new List<string>();
Type[] AllTypesInThisAssembly = Assembly.GetAssembly(typeof(UserChoices)).GetTypes();
foreach (Type _currentType in AllTypesInThisAssembly)
if (_currentType.IsSubclassOf(typeof(UserChoices)))
LeftHandedUserChoices.Add(_currentType.Name);
return LeftHandedUserChoices;
Cheers,
Q
You have a couple of options for doing this. You could use an attribute on your type for the description, or put it in a static field/property on the Type and retrieve that using reflection.
If localization is an issue, you will probably want to store the resource string name, and display the resource value at runtme.
Add custom C# Attributes to your types.
One method is for you to parse class names based on the naming convention you are using (looks like Pascal in your case). For instance RacingBikeDesigner will become Racing Bike Designer. Here is a parsing example.
ATM i cant quiet imagine how this will work. I'm sure it can be done. I notice a pattern use in my attribute where i always use 3 specific attributes together. Take the below as an example
[MyAttr(4, #"a"),
MyAttr(41, "b"),
MyAttr(45, "ab")]
Mine is much more complicated but i would like to define one attribute with more params to generate the data above. How might i do that? Lets say my one attribute will look like this
MyAttr2(4, 41, "a", "b"); //4+41=45, "a"+"b" = "ab"
How might i generate the 3 MyAttr to apply to a class using MyAttr2?
The C# compiler can't convert a single attribute entry into multiple ones in the assembly metadata. However, you could model your attribute in such as way that it exposes additional attribute information as properties (or a collection). However, the child information will not be accessible directly via reflection as independent attributes.
I'm probably just doing this wrong, i know.
I'm using custom serialization and when the xml is generated it's putting the class name as the root element
Example:
<MyClassName>
<MyIntendedRootNode>
<ObjectType>
<Property1/>
<Property2/>
...
I'm invoking the serialization by calling xmlserializer.Serialize(writer,Me) so I'm sure that has something to do with it.
I've tried putting XMLRoot onto the class, but I think as vb is compiling this partial class with its aspx page, it's either overwriting this property or ignoring it entirely.
Ideally I'd like to just tell it to either throw away everything it has and use a different root element.
Anybody else do this except me?
Thanks
You can use either IXmlSerializable or use the XML attributes. I use XmlSerializer passing the root in the constructor.
var MemoryStream ms;
var customRoot = dataObject as XmlRootAttribute;
var xml = new XmlSerializer(dataObject.GetType(), customRoot);
xml.Serialize(ms, dataObject);
In ASP.NET, the actual class that is loaded is a generated class that inherits from your class. (It turns out--surprisingly--that this generated code is actually separate from the additional generated code that is combined with your code using the partial class technique. The generated class has the same name as the class you are working on, but it is in a different namespace.) Since XmlRoot is not an inherited attribute, the XmlSerializer does not see it.
I don't think there is any solution (other than modify the document after you have generated it).
Are you trying to serialize a codebehind file?
I would suggest writing a model to contain the data that needs to be saved, and then serializing that instead. Then use the appropriate XMLWriter attributes to make sure your root element is correctly named.
Or you could implement IXmlSerializable and have full control over your Xml but its a bit of extra effort just to change a root element name.
You can create a wrapper class and give that wrapper class with the name that you wish to be shown in the xml root.