【问题标题】:XmlDeserialize cdata and its siblingsXmlDeserialize cdata 及其兄弟
【发布时间】:2018-04-07 16:25:56
【问题描述】:

我正在将自定义的不灵活 XML 模式反序列化为 C# 对象,以遍历和迁移其中的数据。

一个简单的例子:

  <Source>
    ...
    <Provider>
      <![CDATA[read 1]]>
      <Identifier><![CDATA[read 2]]></Identifier>
      <IdentificationScheme><![CDATA[read 3]]></IdentificationScheme>
    </Provider>
    ...
  </Source>

我正在使用第一个 CDATA 元素值 read 1 反序列化 Provider 元素,它也是同级元素值 read 2read 3

使用http://xmltocsharp.azurewebsites.net/ 会产生以下对象:

[XmlRoot(ElementName = "Provider")]
public class Provider
{
    [XmlElement(ElementName = "Identifier")]
    public string Identifier { get; set; }
    [XmlElement(ElementName = "IdentificationScheme")]
    public string IdentificationScheme { get; set; }
}

[XmlRoot(ElementName = "Source")]
public class Source
{
    [XmlElement(ElementName = "Provider")]
    public Provider Provider { get; set; }
}

但它没有考虑 CDATA 值,事实上我认为像这样反序列化它的值是无法达到的。

我认为这也可能与要使用的 XmlDeserializer 有关,我计划使用 RestSpharp(因为它已经是网站的库)或 System.Xml.Link.XDocument,但我不确定是否可以处理这种情况?

在我的搜索中,我也找不到示例,但堆栈确实建议了这个 <!{CDATA[]]> and <ELEMENT> in a xml element,这正是相同的架构选项。

非常感谢您提前提供的任何帮助,

编辑 1 据我所知,[XmlText] 是所需的解决方案,正如下面 Marc Gravell 的回答中所指出的那样,但它不起作用/在 RestSharp 的 XmlDeserializer 上实现,但需要进一步测试以确定这一点。

【问题讨论】:

    标签: c# traversal cdata xml-deserialization


    【解决方案1】:

    CDATA 本质上只是转义语法,由大多数读者处理。您正在寻找的是:

    [XmlText]
    public string WhateverThisIs { get; set; }
    

    在具有原始内容的对象上。通过将其添加到ProviderWhateverThisIs 得到"read 1" 的值。其他 2 个属性已经正确反序列化为 "read 2""read 3",您无需执行任何操作。

    作为参考,这里的所有内容在没有 CDATA 的情况下几乎表现相同(存在一些空白问题):

    <Provider>
      read 1
      <Identifier>read 2</Identifier>
      <IdentificationScheme>read 3</IdentificationScheme>
    </Provider>
    

    【讨论】:

    • 是的,它被称为混合内容,只是通过 depper 搜索发现的,但是 stackoverflow.com/a/25997011/271433 上的解决方案是一个数组,我假设只要只有一个 CDATA 你的答案就可以吗?跨度>
    • @PedroCosta 忘记 CDATA - 这不是这里的问题(请参阅我的编辑);但是,是的,只要您只有一个其中的随机内容,它就可以正常工作。
    • 嗯,除了Text 属性之外的所有内容都被RestSharp 的Deserializer xmlDeserializer.Deserialize&lt;List&lt;Av&gt;&gt;(response) 填充,是时候试试默认的了:D
    • 使用默认值是一种享受:D List&lt;Av&gt; results = ((EFG)serializer.Deserialize(reader)).Av; 但必须对根节点更严格,因此EFG
    • 抱歉应该澄清一下,EFG 是文档根AV 是具有SourceProvider 的节点,就像问题中的架构一样,cmets 只是关于反序列化方法答案支持。
    猜你喜欢
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多