Как получить значение узла XML в виде строки при десериализации
Я отправляю XML в web-интерфейс ядра aspnet. Значение префикса пространства имен 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>
Для десериализации этого я сделал класс 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 - поэтому у меня нет определения класса. То есть Addenda
узел может содержать n узлов, о которых я не знаю, информация проверяется на стороне получателя. Например, клиент может попросить добавить узел с номером заказа, другой может попросить имя покупателя. И т.п.
Если мне нужно получить все Addenda
содержимое узла в виде строки, как я должен объявить его в классе?
1 ответ
Вы можете десериализовать произвольные данные XML в свободной форме, используя 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; }
}
Пример рабочей.Net скрипки № 1.
Или вы можете устранить 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; }
}
Пример рабочей.Net скрипки № 2.
Заметки:
При применении без имени элемента,
[XmlAnyElement]
указывает, что член является массивомXmlElement
или жеXmlNode
объекты, которые будут содержать все произвольные данные XML, которые не связаны с каким-либо другим членом в содержащем типе.При применении с именем элемента (и необязательным пространством имен),
[XmlAnyElement("Addenda")]
указывает, что член является либо однимXmlElement
объект или массив таких объектов, и будет содержать все произвольные элементы XML с именем<Addenda>
, Использование этой формы устраняет необходимость в дополнительномAddenda
тип.Объединяя
[XmlText]
с[XmlAnyElement]
позволяет десериализовать произвольный смешанный контент.Если вы используете.NET Core, вам может понадобиться nuget System.Xml.XmlDocument.