我正在尝试反序列化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>
我正在阅读和写作:
var serializer = new XmlSerializer(typeof(XmlResult));
using (var reader = new XmlTextReader(@"myxml.xml"))
element = (XmlResult)serializer.Deserialize(reader);
using (var writer = new XmlTextWriter(@"myxml-Copy.xml", Encoding.UTF8))
serializer.Serialize(writer, element);
反序列化后希望的行为是,它等于原始文件:
<returns>An alternate url for the bundle <b>when it is stored</b> in a content delivery network.</returns>
反序列化后的实际行为是
<returns>An alternate url for the bundle in a content delivery network.</returns>
<b>...</b>
中的全文已消失。 (因为它不是一个单独的对象,我知道)
知道怎么解决它,未定义的xml元素留在字符串中吗?或者,至少,我得到了全文? <b>
对我来说并不重要。
答案 0 :(得分:2)
假设我们有以下类:
[XmlRoot("member")]
public class Member
{
[XmlElement("summary")]
public string Summary { get; set; }
[XmlIgnore]
public string Returns { get; set; }
}
订阅XmlSerializer
至UnknownElement
活动。
在事件处理程序中手动将我们的属性设置为数据。
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);
但是,在这种情况下,序列化将与原始数据不同。
答案 1 :(得分:1)
XmlTextReader正在尝试解析HTML,就好像它是XML一样。但XML不允许您在另一个标记的内容中嵌套标记:
<parent_tag> tag text part 1 <nested_tag> illegal inside the content of parent_tag </nested_tag> tag text part 2 </parent_tag>
这是合法的,但对你没什么帮助
<parent_tag>
<part_1> tag text part 1 </part_1>
<nested_tag> now ok as in the hierarchy of parent_tag </nested_tag>
<part_2> tag text part 2 </part_2>
</parent_tag>
@ jdweng建议将<b>
替换为<b>
,将</b>
替换为</b>
是最简单的建议。您还必须处理所有其他嵌入式代码,例如<a>
,<i>
,<strong>
,<em>
等。
您也可以尝试使用它来处理任何HTML。请注意,您不能在HTML中的任何位置拥有CEND序列,即]]>
。
<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>
CDATA部分告诉XML解析器将内容视为文字文本。
您可以预处理XML文件(作为纯文本),在所有<member> ... </member>
标记内的任何文本周围插入CDATA和CEND标记。
答案 2 :(得分:0)
我们遇到了类似的问题。我认为我可以和XmlDocument对象一起使用,并利用带有少许xpath的SelectSingleNode或SelectNodes方法,从而能够提取所需的内容。
string sInformationSource = "a really long string with an xml which contains html to be converted into pdfs.";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(sInformationSource)
XmlNodeList docsHtmlList = xdoc.SelecetNodes("pdf-generator/source-content/document/.");
之后,只需从每个XmlNode获取InnerText。