反序列化时如何将 XML 节点值作为字符串获取 [英] How to get an XML node value as string when deserializing

查看:26
本文介绍了反序列化时如何将 XML 节点值作为字符串获取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在向 aspnet 核心 web api 发送一个 XML.命名空间前缀 cfdi: 的值在包含节点中定义:

I am sending a XML to a aspnet core web api. The value for the namespace prefix cfdi: is defined in a containing node:

<cfdi:Comprobante>
  <cfdi:Conceptos>
  </cfdi:Conceptos>
  <cfdi:Addenda>
    <bfa2:AddendaBuzonFiscal version="2.0" xmlns:bfa2="http://www.buzonfiscal.com/ns/addenda/bf/2"><bfa2:TipoDocumento nombreCorto="FAC" descripcion="Factura"/><bfa2:CFD totalConLetra="CINCUENTA Y DOS MIL QUINIENTOS OCHENTA Y NUEVE PESOS 64/100 M.N." observaciones="OBSERVACIONES"/><bfa2:Extra atributo="ClaveTransportista" valor="00328"/><bfa2:Extra atributo="NoRelacionPemex" valor="1-2"/>
    <bfa2:Extra atributo="NoConvenio" valor="5"/>
    </bfa2:AddendaBuzonFiscal>
    <Encabezado NumOrden="" NumFacturaOriginal="" FechaDePedido=""/>
    <Envio Calle="" NoExterior="" Colonia="" Localidad="" Municipio="" Estado="" Pais="" CodigoPostal="" NombreEnviar=""/><Detalle OrdenCompraLinea="10" GRNumber="GRN"/><Detalle OrdenCompraLinea="10" GRNumber="GRN"/><Detalle OrdenCompraLinea="10" GRNumber="GRN"/>
  </cfdi:Addenda>
</cfdi:Comprobante>

为了反序列化,我创建了 Compprobante 类:

To deserialize this I made the class Comprobante:

public class Comprobante : IValidatableObject
{
    [Required]
    [XmlArray("Conceptos"), XmlArrayItem(typeof(Concepto), ElementName = "Concepto")]
    public List<Concepto> Conceptos { get; set; }

    public Addenda Addenda { get; set; }
}

一切都映射到类属性,但 Addenda 节点可以接收任何东西——任意数量的有效 XML 节点——所以我没有类定义.IE.Addenda 节点可能包含 n 个我不知道的节点,信息在接收端进行验证.例如,客户可以要求添加具有采购订单编号的节点,另一个可以要求买方名称.等

Everything is mapped to the class properties but the Addenda node could receive anything -- any number of valid XML nodes -- so I don´t have a class definition. I.e. the Addenda node could contain n nodes that I don’t know about, the information is validated in the recipient end. For example a customer could ask to add a node with a PO number, another could ask for buyer name. Etc.

如果我需要将所有 Addenda 节点内容作为字符串获取,我应该如何在类中声明它?

If I need to get all the Addenda node content as string, how should I declare it in the class?

推荐答案

您可以使用 XmlSerializer 通过使用 [XmlAnyElement].

You can deserialize arbitrary, free-form XML data using XmlSerializer by marking target properties with [XmlAnyElement].

例如您可以按如下方式定义 Addenda 类型:

E.g. you can define your Addenda type as follows:

[XmlRoot("Comprobante", Namespace = "http://cfdi")]
public class Comprobante : IValidatableObject
{
    [Required]
    [XmlArray("Conceptos"), XmlArrayItem(typeof(Concepto), ElementName = "Concepto")]
    public List<Concepto> Conceptos { get; set; }

    public Addenda Addenda { get; set; }
}

public class Addenda
{
    [XmlAnyElement]
    [XmlText]
    public XmlNode[] Nodes { get; set; }
}

示例 工作 .Net fiddle #1.

或者,您可以完全消除 Addenda 类型并将其替换为 XmlElement 包含类型中的属性:

Or, you could eliminate the Addenda type completely and replace it with an XmlElement property in the containing type:

[XmlRoot("Comprobante", Namespace = "http://cfdi")]
public class Comprobante : IValidatableObject
{
    [Required]
    [XmlArray("Conceptos"), XmlArrayItem(typeof(Concepto), ElementName = "Concepto")]
    public List<Concepto> Conceptos { get; set; }

    [XmlAnyElement("Addenda")]
    public XmlElement Addenda { get; set; }
}

示例 工作 .Net fiddle #2.

注意事项:

  • 当应用没有元素名称时,[XmlAnyElement] 指定该成员是 XmlElementXmlNode 对象的数组,这些对象将包含所有未绑定到包含类型中的其他成员的任意 XML 数据.

  • When applied without an element name, [XmlAnyElement] specifies that the member is an array of XmlElement or XmlNode objects which will contain all arbitrary XML data that is not bound to some other member in the containing type.

当应用元素名称(和可选命名空间)时,[XmlAnyElement("Addenda")] 指定该成员是单个 XmlElement 对象或此类对象的数组,并将包含所有名为 的任意 XML 元素.使用这种形式不需要额外的 Addenda 类型.

When applied with an element name (and optional namespace), [XmlAnyElement("Addenda")] specifies that the member is a either a single XmlElement object or an array of such objects, and will contain all arbitrary XML elements named <Addenda>. Using this form eliminates the need for the extra Addenda type.

结合[XmlText][XmlAnyElement] 允许反序列化任意混合内容.

Combining [XmlText] with [XmlAnyElement] allows arbitrary mixed content to be deserialized.

如果您使用 .NET Core,您可能需要 nuget 系统.Xml.XmlDocument.

If you are using .NET Core you may need to nuget System.Xml.XmlDocument.

这篇关于反序列化时如何将 XML 节点值作为字符串获取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆