3

I am trying to read component data using Tridion Core api. I am able to get all the details except body field. If i comment out the body field, then i will get correct data. Body field contains Richtext data. during deserilization it throws following error

"Unexpected node type Element. ReadElementString method can only be called on elements with simple or empty content. Line 5, position 6.",

below is the code for Article Class

[Serializable, XmlRoot("Content", IsNullable = true), XmlType("Content")]
public class ArtilceXMlEntities
{
    [XmlIgnore]
    public string TcmId { get; set; }

    [XmlElement("Header")]
    public string Header { get; set; }

    [XmlElement("Summary")]
    public string Summary { get; set; }

    [XmlIgnore]
    public string BodyText { get; set; }
    [XmlElement("Body")]
    public string Body
    {
        get { return "<![CDATA[" + BodyText + "]]>"; }
        set { BodyText = value; }
    }

    [XmlElement("Author")]
    public Author Author { get; set; }
    [XmlElement("Date")]
    public string Date { get; set; }
    [XmlElement("ViewDetail", IsNullable = true)]
    public string ViewDetail { get; set; }

    [XmlElement("IsPublished")]
    public string IsPublished { get; set; }

    [XmlElement("ReadMoreText")]
    public string ReadMoreText { get; set; }
    [XmlElement("Thumbnail")]
    public string Thumbnail { get; set; }
    [XmlElement("TagList")]
    public List<ArticleTags> TagList { get; set; }

Deserialize function

public static ArtilceXMlEntities Deserialize(string xml)
{
    ArtilceXMlEntities result;
    xml = RemoveAllNamespaces(xml);
    using (StringReader stringReader = new StringReader(xml))
    using (XmlReader xmlReader = XmlReader.Create(stringReader))
    {
        //XmlRootAttribute xRoot = new XmlRootAttribute();
        //xRoot.ElementName = "Content";
        //xRoot.Namespace = "uuid:5069fa38-9114-42bc-8399-232eefafe5cd";
        //xRoot.IsNullable = true;
        XmlSerializer serializer = new XmlSerializer(typeof(ArtilceXMlEntities));
        result = (ArtilceXMlEntities)serializer.Deserialize(xmlReader);
    }
    return result;
}

//Implemented based on interface, not part of algorithm
public static string RemoveAllNamespaces(string xmlDocument)
{
    XElement xmlDocumentWithoutNs = RemoveAllNamespaces(XElement.Parse(xmlDocument));

    return xmlDocumentWithoutNs.ToString();
}

//Core recursion function
private static XElement RemoveAllNamespaces(XElement xmlDocument)
{
    if (!xmlDocument.HasElements)
    {
        XElement xElement = new XElement(xmlDocument.Name.LocalName);
        xElement.Value = xmlDocument.Value;

        foreach (XAttribute attribute in xmlDocument.Attributes())
            xElement.Add(attribute);

        return xElement;
    }
    return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
} 

Reading data by tridion core api

//_client is Tridion core service proxy client, which works fine , tcm id is the component id 
var item = (ComponentData)_client.Read(tcmId, new ReadOptions());
var ArticleObj = ArtilceXMlEntities.Deserialize(item.Content);

I am unable to deserialize the body field, which contains rich text "<div xmlns='http://www.w3.org/1999/xhtml'><h1>asdasd ad</h1> Test Body</div>"

Please guide me to solve the issues.

3
  • Never had issues with this - I would suggest comparing what you're doing with the approach followed here: code.google.com/p/tridion-practice/wiki/ChangeContentOrMetadata
    – Nuno Linhares
    Commented Dec 26, 2014 at 14:09
  • You're removing namespaces from the XML, but from the looks of it not from the XHTML in the rich-text field. I guess you should also remove the namespaces there, although I'm not that familiar with .NETs XML deserializer. Commented Dec 26, 2014 at 14:23
  • 1
    I'd suggest you spend some more time looking at your code, and perhaps reading the documentation on what the deserializer needs. Why do I say this? Because the code you've posted is inconsistently cased and has spelling mistakes. If you care so little about it, why should anyone else? Commented Dec 27, 2014 at 20:25

1 Answer 1

5

Your question/problem is not specific to Tridion, but a general question on how to deserialize XML mixed content using the XmlSerializer. Note that the content of a "rich text field" (a.k.a. XHTML field) is mixed content in XML. That is: it is text content mixed with XML elements from the XHTML namespace.

You currently map the "Body" field to a property of type String; the XmlSerializer doesn't expect mixed content in that case (I see you're already trying to bypass serialization issues by putting the content in a CDATA section in the property getter, but that is not compatible with how Tridion represents the XHTML content and it's not solving your deserialization issue either).

I'm not sure if it's possible to let the XmlSerializer (de-)serialize such mixed content; you could try changing the type of the Body property to XmlElement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.