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.

  • 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 Dec 26 '14 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. – Frank van Puffelen Dec 26 '14 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? – Dominic Cronin Dec 27 '14 at 20:25
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, privacy policy and cookie policy

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