反序列化时如何将 XML 节点值作为字符串获取
How to get an XML node value as string when deserializing
我正在向 aspnet 核心网站 api 发送 XML。名称空间前缀 cfdi:
的值在包含节点中定义:
<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>
为了反序列化这个,我做了 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; }
}
一切都映射到 class 属性,但是 Addenda
节点可以接收任何东西——任意数量的有效 XML 节点——所以我没有 class定义。 IE。 Addenda
节点可能包含 n 个我不知道的节点,信息在接收端验证。例如,客户可能会要求添加一个带有 PO 编号的节点,另一个客户可能会要求提供买家姓名。等等
如果我需要获取所有Addenda
节点内容为字符串,我应该如何在class中声明它?
您可以使用 XmlSerializer
通过使用 [XmlAnyElement]
.
标记目标属性来反序列化任意、自由格式的 XML 数据
例如您可以按如下方式定义 Addenda
类型:
[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; }
}
或者,您可以完全删除 Addenda
类型并在包含类型中用 XmlElement
属性 替换它:
[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; }
}
备注:
当应用没有元素名称时,[XmlAnyElement]
指定成员是XmlElement
或[=19=的数组] 对象将包含所有任意 XML 数据,这些数据未绑定到包含类型中的某些其他成员。
当应用 元素名称(和可选的命名空间)时,[XmlAnyElement("Addenda")]
指定该成员是单个 XmlElement
对象或此类对象的数组,并将包含所有名为 <Addenda>
的任意 XML 元素。使用这种形式就不需要额外的 Addenda
类型。
结合[XmlText]
和[XmlAnyElement]
允许反序列化任意混合内容。
如果您使用的是 .NET Core,您可能需要 nuget System.Xml.XmlDocument.
我正在向 aspnet 核心网站 api 发送 XML。名称空间前缀 cfdi:
的值在包含节点中定义:
<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>
为了反序列化这个,我做了 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; }
}
一切都映射到 class 属性,但是 Addenda
节点可以接收任何东西——任意数量的有效 XML 节点——所以我没有 class定义。 IE。 Addenda
节点可能包含 n 个我不知道的节点,信息在接收端验证。例如,客户可能会要求添加一个带有 PO 编号的节点,另一个客户可能会要求提供买家姓名。等等
如果我需要获取所有Addenda
节点内容为字符串,我应该如何在class中声明它?
您可以使用 XmlSerializer
通过使用 [XmlAnyElement]
.
例如您可以按如下方式定义 Addenda
类型:
[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; }
}
或者,您可以完全删除 Addenda
类型并在包含类型中用 XmlElement
属性 替换它:
[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; }
}
备注:
当应用没有元素名称时,
[XmlAnyElement]
指定成员是XmlElement
或[=19=的数组] 对象将包含所有任意 XML 数据,这些数据未绑定到包含类型中的某些其他成员。当应用 元素名称(和可选的命名空间)时,
[XmlAnyElement("Addenda")]
指定该成员是单个XmlElement
对象或此类对象的数组,并将包含所有名为<Addenda>
的任意 XML 元素。使用这种形式就不需要额外的Addenda
类型。结合
[XmlText]
和[XmlAnyElement]
允许反序列化任意混合内容。如果您使用的是 .NET Core,您可能需要 nuget System.Xml.XmlDocument.