Attribute format to element in XAML serialization - c#

When I serialize this POCO using XamlServices.Save():
public class GtdConfig
{
public string LocalDbInstanceName { get; set; }
}
The .xaml file will be:
<GtdConfig LocalDbInstanceName="v12.0">
</GtdConfig>
How can I get the file like this:
<GtdConfig>
<GtdConfig.LocalDbInstanceName>v12.0</GtdConfig.LocalDbInstanceName>
</GtdConfig>
For XML serailziation, there are XmlElementAttribute and XmlAttributeAttribute to do this. But I cannot find these attributes in XAML serialization.

Related

Serializing ArrayList outputs ArrayOfAnyType

I do have a problem with serializing a ArrayList. Most propably I use wrong XML Attributes for it since I when I changed them it would not even serialize it and got errors like 'The type may not be used in this context.'
I need to use a non generic ArrayList. On adding [XmlArray("LineDetails")] made this code to run but the output is not correct, it should give me the LineDetails structure. Any idea how to fix this?
This is a part of a whole xml like Document > Header > LineCollection > LineDeatails.
The problem is only with this details if I use a standard string field it is ok but the range of the colletion if changing with every document.
[XmlType(TypeName = "LineCollection")]
public class LineCollection
{
public String LineCount{ get; set; }
// [XmlElement(ElementName = "LineDetails")]
[XmlArray("LineDetails")]
public ArrayList LineDetails{ get; set; }
}
public class LineDetails: ArrayList
{
public String LineNum{ get; set; }
public String ItemId{ get; set; }
public String ItemName{ get; set; }
//... only strings
}
public class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => new UTF8Encoding(false);
}
public string Serialize()
{
// var xmlserializer = new XmlSerializer(this.GetType());
var xmlserializer = new XmlSerializer(this.GetType(), new Type[] { typeof(LineDetails) });
var Utf8StringWriter = new Utf8StringWriter();
var xns = new XmlSerializerNamespaces();
xns.Add(string.Empty, string.Empty);
using (var writer = XmlWriter.Create(Utf8StringWriter))
{
xmlserializer.Serialize(writer, this, xns);
return Utf8StringWriter.ToString();
}
}
And the incorrect output of this...
<LineColletion>
<LineDetails>
<anyType xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="ArrayOfAnyType"/>
<anyType xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="ArrayOfAnyType"/>
<anyType xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="ArrayOfAnyType"/>
</LineDetails>
</LineColletion>
it should be like this
<LineColletion>
<LineDetails>
<LineNum>1</LineNum>
<ItemId>Item_2321</ItemId>
<ItemName>TheItemName</ItemName>
</LineDetails>
<LineDetails>
<LineNum>2</LineNum>
<ItemId>Item_232100000</ItemId>
<ItemName>TheItemName0</ItemName>
</LineDetails>
<LineDetails>
<LineNum>3</LineNum>
<ItemId>Item_23217777</ItemId>
<ItemName>TheItemName7</ItemName>
</LineDetails>
</LineColletion>
Now the wrong xml looks like this...
<LineDetails>
<anyType xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="LineDetails">
<LineNum>1</LineNum>
<ItemId>Item_2321</ItemId>
<ItemName>TheItemName</ItemName>
</anyType>
<anyType xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="LineDetails">
<LineNum>2</LineNum>
<ItemId>Item_2321</ItemId>
<ItemName>TheItemName</ItemName>
</anyType>
</LineDetails>
You may generate the required XML by modifying your data model as follows:
[XmlType(TypeName = "LineColletion")] // Fixed: TypeName. But do you want LineColletion (misspelled) or LineCollection (correctly spelled)? Your XML shows LineColletion but your code used LineCollection.
public class LineCollection
{
public String LineCount{ get; set; }
[XmlElement("LineDetails", typeof(LineDetails))] // Fixed -- specify type(s) of items in the ArrayList.
public ArrayList LineDetails{ get; set; }
}
public class LineDetails // Fixed: removed inheritance from ArrayList.
{
public String LineNum{ get; set; }
public String ItemId{ get; set; }
public String ItemName{ get; set; }
//... only strings
}
Notes:
Your model makes LineDetails inherit from ArrayList. XmlSerializer will never serialize collection properties, it will only serialize collection items. In order to serialize it correctly, I removed the inheritance since you don't seem to be using it anyway.
If you really need LineDetails to inherit from ArrayList, you will need to implement IXmlSerializable or replace it collection with a DTO.
Implementing IXmlSerializable is tedious and error-prone. I don't recommend it.
Your LineDetails collection is serialized without an outer wrapper element. To make the serializer do this, apply XmlElementAttribute to the property.
ArrayList is an untyped collection, so you must inform XmlSerializer of the possible types it might contain. You have two options:
Assigning a specific type to a specific element name by setting XmlElementAttribute.Type (or XmlArrayItemAttribute.Type), OR
Adding xsi:type attributes by informing the serializer of additional included types. You are doing this by passing them into the constructor, which is why you are seeing the p5:type="LineDetails" attribute.
Since you don't want the attributes, you need to set the element name by setting the type like so:
[XmlElement("LineDetails", typeof(LineDetails))]
The XML element corresponding to your LineCollection is named <LineColletion>. Note that the spelling is inconsistent. You will need to set [XmlType(TypeName = "LineColletion")] to the name you actually want.
Demo fiddle here.

C# - How to convert complex json to XML with name and value property to tags

Trying convert json to XML with JsonConvert.DeserializeXmlNode(Json.ToString()) and its works but not expected,
First Exapmle:
JSON :
"Emailid": ""
Converted XML :
<Emailid></Emailid>
First example working as expected
Second Example:
JSON :
"ProposalDate": {
"Name": "Proposal Date",
"Value": "06/05/2019"
}
Converted XML :
<ProposalDate>
<Name>Proposal Date</Name>
<Value>06/05/2019</Value>
</ProposalDate>
Expected XML for second example:
<ProposalDate Name="Proposal Date" Value="06/05/2019" />
but for second example want ProposalDate tag with Name and Value property.
What should i do ?
You could deserialize JSON to a class first, apply [XmlAttribute] to the class properties and then serialize the class to XML. See the XmlAttributeAttribute Class documentation.
Your class would look something like this:
public class ProposalDate
{
[XmlAttribute]
public string Name { get; set; }
[XmlAttribute]
public string Value { get; set; }
}
Deserializing JSON to object and serializing object to XML are well documented, and examples easily found.

Difference between XmlElement and XmlElementAttribute in c# xml serialization

What is difference between XmlElement and XmlElementAttribute in c# xml serialization. I am facing an issue while xml serialization of an object.
Actually, I have 2 fields with the same name. 1 in Base class and other in child class and I need to set different element names for those to show in xml doc.
Well, It depends on your XML file structure. If the child element is a an xml tag, you should add XmlElement data annotation. If the property of your class is bound to an attribute related to the current node, then add an attribute data annotation.
[Serializable()]
public class Person
{
[System.Xml.Serialization.XmlElement("Name")]
public string Name{ get; set; }
[System.Xml.Serialization.XmlElement("Phone")]
public int Phone { get; set; }
[System.Xml.Serialization.XmlElement("Address ")]
public string Address { get; set; }
}
In this case your xml structure should like this:
<person>
<name>...</name>
<phone>...</phone>
<address>...</address>
</person>
Now if the properties represents child attributes, it will be like this:
<person name='...' phone='...' address='...'></person>

Serialization of array of xml elements already within a xmlAny Element

<Fruits>
<FruitName>Amla</FruitName>
<FruitPrice>10 US DOLLARS</FruitPrice>
<Origin>
<Country>INDIA</Country>
<NativeName>GOOSEBERRY</NativeName>
<Availability>PLENTY</Availability>
</Origin>
<OtherInfo>
<FiberPercentage>1.11</FiberPercentage>
<MagnesiumPercentage>0.02</MagnesiumPercentage>
</OtherInfo>
While De serializing the above XML structure, I use something like,
Xml
XmlElement("FruitsList")]
public List<Fruits> FruitsImport { get; set; }
In Fruits Class, I have something like:
[XmlAnyElement]
public List<XmlElement> FruitElements { get; set; }
[XmlElement("Origin")]
public List<XmlElement> FruitOrigin { get; set; }
[XmlElement("OtherInfo")]
public List<XmlElement> OtherInfo { get; set; }
FruitElement retrieves the FruitName and FruitPrice.
FruitOrigin retrives Country Info alone.
OtherInfo retrives FiberPercentage alone.
Any ideas on how to get all the info under <Origin> and <OtherInfo> tags ?
Because you have elements nested in both <origin> and <otherinfo> tags, you need to define a class for them as well when performing deserialization.
[XmlElement("Origin")]
public List<Origins> FruitOrigin { get; set; }
You would define the origin class the same way as you did for fruit class.
(The skeleton of Origin class would be something as below:
[Serializable]
public class Origin
{
[XmlAnyElement]
public List<XmlElement> OriginElements { get; set; }
}
)
The best way is to write XSD schema for the XML and generate class from XSD schema using XSD.exe, this way you can validate that always XML and class matches to XSD and never have issue with Serialization/ Deserialization.
You can create batch file like below to generate class from xsd schema:
del Configuration.AutoGenerated.cs
"%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\bin\xsd" Test.Configuration.xsd /c /n:Test.Configuration
rename Test_Configuration.cs Configuration.AutoGenerated.cs
pause
You can see more usage examples at above link for XSD.exe.
It will generate partial classes so you can easily extend it further if required.

Class Fields to XML Element and attribute

I have the following class that I want to serialize to an XML file
public class HDLCParameters
{
[XmlElement("ClientMACAddress")]
public string ClientMACAddress { get; set; }
}
this is serialized like this:
<HDLCParameters>
<ClientMACAddress>0x10</ClientMACAddress>
</HDLCParameters>
but i need it like this:
<HDLCParameters>
<ClientMACAddress value="0x10" />
</HDLCParameters>
Do i need to create a ClientMACAddress class with a "value" field? isn't there a way to set an element and an attribute with its value?
thanks
Create the ClientMACAddress class, give it a value field, and specify that it's an attribute (XmlAttributeAttribute)

Categories

Resources