Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>TLDR:</strong> Use <code>XmlSerializer</code> to deserialize from xml dialects you can't control; <code>ServiceStack</code> is designed for code-first development and <strong>can not</strong> be adapted to general purpose xml parsing.</p> <hr> <p>ServiceStack.Text does <em>not</em> implement a custom Xml serializer - it uses <code>DataContractSerializer</code> under the hood. <code>FromXml</code> is merely syntactic sugar.</p> <h2>Using <code>DataContractSerializer</code> to parse Xml</h2> <p>As you've noticed, <code>DataContractSerializer</code> is picky about <strong>namespaces</strong>. One approach is to specify the namespace explicitly on the class, but if you do this, you'll need to specify <code>[DataMember]</code> everywhere since it assumes that if anything is explicit, everything is. You can work around this problem using an assembly-level attribute (e.g. in AssemblyInfo.cs) to declare a default namespace:</p> <pre><code>[assembly: ContractNamespace("", ClrNamespace = "My.Namespace.Here")] </code></pre> <p>This solves the namespace issue.</p> <p>However, you cannot solve 2 other issues with DataContractSerializer:</p> <ul> <li>It will not use attributes (in your case, <code>version</code>)</li> <li>It requires that collections such as <code>item</code> have both a wrapping name and an element name (something like items and item)</li> </ul> <p>You cannot work around these limitations because <strong><code>DataContractSerializer</code> is not a general-purpose XML parser</strong>. It is intended to easily produce and consume an API, not map arbitrary XML onto a .NET datastructure. You will never get it to parse rss; so therefore ServiceStack.Text (which just wraps it) can also not parse it.</p> <p>Instead, use <code>XmlSerializer</code>.</p> <h2>Using <code>XmlSerializer</code></h2> <p>This is rather straighforward. You can parse input with something along the lines of:</p> <pre><code>var serializer = new XmlSerializer(typeof(RSS)); RSS rss = (RSS)serializer.Deserialize(myXmlReaderHere); </code></pre> <p>The trick is to annotate the various fields such that they match your xml dialect. For example, in your case that would be:</p> <pre><code>[XmlRoot("rss")] public class RSS { [XmlAttribute] public string version { get; set; } public ChannelClass channel { get; set; } } public class ChannelClass { public string title { get; set; } public string ttl { get; set; } public string description { get; set; } public string link { get; set; } public string copyright { get; set; } public string language { get; set; } public string pubDate { get; set; } [XmlElement] public List&lt;ItemClass&gt; item { get; set; } } public class ItemClass { public string title { get; set; } public string link { get; set; } public string description { get; set; } public string guid { get; set; } } </code></pre> <p>So some judicious attributes suffice to get it to parse the XML as you want.</p> <p>In summary: you <strong>cannot</strong> use ServiceStack for this since it uses <code>DataContractSerializer</code>.ServiceStack/<code>DataContractSerializer</code> are designed for scenarios where you control the schema. <strong>Use <code>XmlSerializer</code> instead.</strong> </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload