C# 反序列化xml,其中字符串可能包含xml/html

C# 反序列化xml,其中字符串可能包含xml/html,c#,xml,serialization,deserialization,C#,Xml,Serialization,Deserialization,我正在尝试反序列化XML,其中元素可能包含html。这里是这样的: <member name="P:System.Web.Optimization.Bundle.CdnPath"> <summary>Gets or sets an alternate url for the bundle when it is stored in a content delivery network.</summary> <returns>An al

我正在尝试反序列化XML,其中元素可能包含html。这里是这样的:

<member name="P:System.Web.Optimization.Bundle.CdnPath">
    <summary>Gets or sets an alternate url for the bundle when it is stored in a content delivery network.</summary>
    <returns>An alternate url for the bundle <b>when it is stored</b> in a content delivery network.</returns>
</member>
反序列化后的期望行为是,它等于原始文件:

<returns>An alternate url for the bundle <b>when it is stored</b> in a content delivery network.</returns>
捆绑包存储在内容交付网络中时的备用url。
反序列化后的实际行为是

<returns>An alternate url for the bundle  in a content delivery network.</returns>
内容交付网络中捆绑包的备用url。
中的整个文本都消失了。(因为它不是一个单独的对象,我知道)
你知道我该如何解决这个问题吗,未定义的xml元素保留在字符串中?或者,至少,我得到了全文?
对我来说并不重要。

假设我们有以下类:

[XmlRoot("member")]
public class Member
{
    [XmlElement("summary")]
    public string Summary { get; set; }
    [XmlIgnore]
    public string Returns { get; set; }
}
订阅
XmlSerializer
UnknowneElement
事件

在事件处理程序中,手动将我们的属性设置为数据

private static void Serializer_UnknownElement(object sender, XmlElementEventArgs e)
{
    var element = (Member)e.ObjectBeingDeserialized;
    element.Returns = e.Element.InnerXml;
}
请注意,属性名称不应与xml节点名称匹配(区分大小写)。只有在这种情况下,才会触发事件。如果名称匹配,请使用
XmlIgnore
属性

然后我们可以按如下方式反序列化数据:

var serializer = new XmlSerializer(typeof(Member));
serializer.UnknownElement += Serializer_UnknownElement;

Member element;
using (var reader = XmlReader.Create(@"test.txt"))
    element = (Member)serializer.Deserialize(reader);

但是,在这种情况下,序列化将不同于原始数据。

XmlTextReader正试图像解析XML一样解析HTML。但XML不允许在另一个标记的内容中嵌套标记:

<parent_tag> tag text part 1 <nested_tag> illegal inside the content of parent_tag </nested_tag> tag text part 2 </parent_tag>
CDATA部分告诉XML解析器将内容视为文本。
您可以预处理XML文件(作为纯文本),在所有
中的任何文本周围插入CDATA和CEND标记标签。

我们遇到了类似的问题。我想我可以使用一个XmlDocument对象,并利用SelectSingleNode或SelectNodes方法和一点XPath魔法。我能提取出我需要的东西

string input= "a really long string with an xml which contains html to be converted to pdfs.";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(input)
XmlNodeList docsHtmlList = xdoc.SelecetNodes("pdf-generator/source-content/document/.");
之后,只需从每个XmlNode获取InnerText

更新不要使用LoadXml,而是切换到:

string input= "a really long string with an xml which contains html to be converted to pdfs.";
XmlDocument xdoc = new XmlDocument();
using (var xmlreader = new XmlTextReader(new StringReader(input)))
{
   xmlreader.XmlResolver = null;
   xmlreader.DtdProcessing = DtdProcessing.Ignore;
   xdoc.Load(xmlreader);
}
XmlNodeList docsHtmlList = xdoc.SelecetNodes("pdf-generator/source-content/document/.");

将文件读取为字符串,并将:替换为:b和替换为:/b,这样我就必须替换所有html标记。听起来好像表现很差。(XML是C#类文档,这里可以是任何HTML)。但是,是的,这也是一个解决方案…这看起来绝对是正确的解决方案。不错。作品感谢这个解决方案,效果非常好。我想知道如何将其应用于字符串数组。这会很好,但这听起来有点像字符串替换、移动、拆分、压缩,。。。但是我正在使用C#library文档(xml),它们可能非常大。我不认为预处理是正确的解决方案。但我想,对于一个小项目,这将是伟大的(这里有我的+1)
<member name="P:System.Web.Optimization.Bundle.CdnPath">
<![CDATA[
    <summary>Gets or sets an alternate url for the bundle when it is stored in a content delivery network.</summary>
    <returns>An alternate url for the bundle <b>when it is stored</b> in a content delivery network.</returns>
]]> 
</member>
string input= "a really long string with an xml which contains html to be converted to pdfs.";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(input)
XmlNodeList docsHtmlList = xdoc.SelecetNodes("pdf-generator/source-content/document/.");
string input= "a really long string with an xml which contains html to be converted to pdfs.";
XmlDocument xdoc = new XmlDocument();
using (var xmlreader = new XmlTextReader(new StringReader(input)))
{
   xmlreader.XmlResolver = null;
   xmlreader.DtdProcessing = DtdProcessing.Ignore;
   xdoc.Load(xmlreader);
}
XmlNodeList docsHtmlList = xdoc.SelecetNodes("pdf-generator/source-content/document/.");