Home > front end >  C# Problem with deserialization xml with arrays in arrays and other names
C# Problem with deserialization xml with arrays in arrays and other names

Time:01-19

I have a problem with creating the appropriate class to deserialize the xml file. The xml structure looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" target-language="pl" datatype="plaintext" original="1112">
        <body>
            <group id="90362">
                <trans-unit id="90362::aff_11">
                    <source>text 1 1</source>
                    <target>text 1 1</target>
                </trans-unit>
                <trans-unit id="90362::aff_12">
                    <source>text 1 2</source>
                    <target>text 1 2</target>
                </trans-unit>
                <trans-unit id="90362::aff_13">
                    <source>text 1 3</source>
                    <target>text 1 3</target>
                </trans-unit>
            </group>
            <group id="90392">
                <trans-unit id="90392::aff_21">
                    <source>text 2 1</source>
                    <target>text 2 1</target>
                </trans-unit>
                <trans-unit id="90392::aff_22">
                    <source>text 2 2</source>
                    <target>text 2 2</target>
                </trans-unit>
                <trans-unit id="90392::aff_23">
                    <source>text 2 3</source>
                    <target>text 2 3</target>
                </trans-unit>    
            </group>  
        </body>
    </file>
</xliff>

As you can see, we have nested arrays within arrays. In addition, one of the arrays has a name that cannot be given the same name for the class. Pre-created classes:

[XmlRoot("xliff", Namespace = "urn:oasis:names:tc:xliff:document:1.2")]
    public class xliff
    {
        public file file { get; set; }
    }

    public class file
    {
        public body body { get; set; }
    }

    public class body : List<group>
    {        
        public List<group> groups { get; set; }
    }

    public class group //: List<trans>
    {        
        public List<trans> trans { get; set; }
    }
        
    public class trans 
    {
        [XmlElement("source")]
        public string source { get; set; }
        [XmlElement("target")]
        public string target { get; set; }
    } 

Unfortunately, I have a problem to complete classes to get to source and target values.

CodePudding user response:

You can use an online tool to convert XML to c# model: https://json2csharp.com/xml-to-csharp

Try to use this model (generated by above tool):

// using System.Xml.Serialization;
// XmlSerializer serializer = new XmlSerializer(typeof(Xliff));
// using (StringReader reader = new StringReader(xml))
// {
//    var test = (Xliff)serializer.Deserialize(reader);
// }

[XmlRoot(ElementName="trans-unit")]
public class Transunit { 

    [XmlElement(ElementName="source")] 
    public string Source { get; set; } 

    [XmlElement(ElementName="target")] 
    public string Target { get; set; } 

    [XmlAttribute(AttributeName="id")] 
    public string Id { get; set; } 

    [XmlText] 
    public string Text { get; set; } 
}

[XmlRoot(ElementName="group")]
public class Group { 

    [XmlElement(ElementName="transunit")] 
    public List<Transunit> Transunit { get; set; } 

    [XmlAttribute(AttributeName="id")] 
    public int Id { get; set; } 

    [XmlText] 
    public string Text { get; set; } 
}

[XmlRoot(ElementName="body")]
public class Body { 

    [XmlElement(ElementName="group")] 
    public List<Group> Group { get; set; } 
}

[XmlRoot(ElementName="file")]
public class File { 

    [XmlElement(ElementName="body")] 
    public Body Body { get; set; } 

    [XmlAttribute(AttributeName="source-language")] 
    public string SourceLanguage { get; set; } 

    [XmlAttribute(AttributeName="target-language")] 
    public string TargetLanguage { get; set; } 

    [XmlAttribute(AttributeName="datatype")] 
    public string Datatype { get; set; } 

    [XmlAttribute(AttributeName="original")] 
    public int Original { get; set; } 

    [XmlText] 
    public string Text { get; set; } 
}

[XmlRoot(ElementName="xliff")]
public class Xliff { 

    [XmlElement(ElementName="file")] 
    public File File { get; set; } 

    [XmlAttribute(AttributeName="version")] 
    public DateTime Version { get; set; } 

    [XmlAttribute(AttributeName="xmlns")] 
    public string Xmlns { get; set; } 

    [XmlText] 
    public string Text { get; set; } 
}

CodePudding user response:

you should not inherit from List<T>. Instead chose composition over inheritance, which means your body-class has a collection of groups, in contrast to your body-class being such a collection.

So you may use this structure instead:

[XmlRoot("xliff", Namespace = "urn:oasis:names:tc:xliff:document:1.2")]
public class xliff
{
    public file file { get; set; }
}

public class file
{
    public body body { get; set; }
}

public class body
{        
    [XmlElement("group")]
    public List<group> groups { get; set; }
}

public class group
{        
    [XmlElement("trans")]
    public List<trans> trans { get; set; }
}
    
public class trans 
{
    [XmlElement("source")]
    public string source { get; set; }
    [XmlElement("target")]
    public string target { get; set; }
} 

Furthermore you should consider to use PascalCase for your classes. To give those classes different names within the serialized xml, you may use the xml-attributes, e.g.:

[XmlRott("body")]
public class Body

CodePudding user response:

XLIFF is far more complex and has far more elements than this. The current version is 2.1 but the older 1.2 is also described in the OASIS site, along with links to the XSD schema

Almost all standardized XML documents are based on an XML schema, available as an XSD document (XML Schema Definition).

You can use the xsd.exe tool to generate C# classes from the XSD file. You can download eg http://docs.oasis-open.org/xliff/v1.2/cs02/xliff-core-1.2-strict.xsd locally as xliff.xsd and then execute

xsd xliff.xsd /c 

To generate the file xliff.cs with all the classes.

The result is over 1000 lines so it can't just be pasted here.

The tree structure, copied from the docs, has a lot of elements :


<xliff>1
| |
|  --- [Extension Point]
| |
 --- <file> 
 |
  --- <header>?
 | |
 |  --- <skl>?
 | | |
 | |  --- (<internal-file> | <external-file>)1
 | |
 |  --- <phase-group>?
 | | |
 | |  --- <phase> 
 | | |
 | |  --- <note>*
 | |
 |  --- <glossary>*
 | | |
 | |  --- (<internal-file> | <external-file>)1
 | |
 |  --- <reference>*
 | | |
 | |  --- (<internal-file> | <external-file>)1
 | |
 |  --- <count-group>*
 | | |
 | |  --- <count>*
 | |
 |  --- <tool>*
 | | |
 | |  --- [Extension Point]
 | |
 |  --- <prop-group>*
 | | |
 | |  --- <prop>*
 | |
 |  --- [Extension Point]
 | |
 |  --- <note>*
 |
  --- <body>1
 |
  --- <group>*
 | |
 |  --- <context-group>*
 | | |
 | |  --- <context> 
 | |
 |  --- <count-group>*
 | | |
 | |  --- <count>*
 | |
 |  --- <prop-group>*
 | | |
 | |  --- <prop>*
 | |
 |  --- [Extension Point]
 | |
 |  --- <note>*
 | |
 |  --- At least one of: (<group>* <trans-unit>* <bin-unit>*)
 |
  --- <trans-unit>*
 | |
 |  --- <source>1
 | | |
 | |  --- [Inline Elements]
 | |
 |  --- <target>?
 | | |
 | |  --- [Inline Elements]
 | |
 |  --- <context-group>*
 | | |
 | |  --- <context> 
 | |
 |  --- <count-group>*
 | | |
 | |  --- <count>*
 | |
 |  --- <prop-group>*
 | | |
 | |  --- <prop>*
 | |
 |  --- <seg-source>?
 | | |
 | |  --- [Inline Elements]
 | |
 |  --- [Extension Point]
 | |
 |  --- <note>*
 | |
 |  --- <alt-trans>*
 | |
 |  --- <context-group>*
 | | |
 | |  --- <context> 
 | |
 |  --- <source>?
 | | |
 | |  --- [Inline Elements]
 | | |  --- <target> 
 | | |
 | |  --- [Inline Elements]
 | |
 |  --- <prop-group>*
 | | |
 | |  --- <prop>*
 | |
 |  --- <seg-source>?
 | | |
 | |  --- [Inline Elements]
 | |
 |  --- [Extension Point]
 | |
 |  ---- <note>*
 |
  --- <bin-unit>*
 |
  --- <bin-source>1 & <bin-target>?
 | |
 |  --- (<internal-file> | <external-file>)1
 |
  --- <context-group>*
 | |
 |  --- <context> 
 |
  --- <count-group>*
 | |
 |  --- <count>*
 |
  --- <prop-group>*
 | |
 |  --- <prop>*
 |
  --- [Extension Point]
 |
  --- <note>*
 |
  --- <trans-unit>*

Struct_Extension_Elements

Inline Elements:

--- --- <ph>*
 | |
 |  --- <sub>*
 | |
 |  --- [Inline Elements]
 |
  --- <it>*
 | |
 |  --- <sub>*
 | |
 |  --- [Inline Elements]
 |
  --- <bpt>*
 | |
 |  --- <sub>*
 | |
 |  --- [Inline Elements]
 |
  --- <ept>*
 | |
 |  --- <sub>*
 | |
 |  --- [Inline Elements]
 |
  --- <g>*
 | |
 |  --- [Inline Elements]
 |
  --- <x/>*
 | |
 |  --- [Inline Elements]
 |
  --- <bx/>*
 | |
 |  --- [Inline Elements]
 |
  --- <ex/>*
 | |
 |  --- [Inline Elements]
 |
  --- <mrk>*
 |
  --- [Inline Elements]
  •  Tags:  
  • Related