Как украсить / определить членов класса для необязательного элемента XML, который будет использоваться с XmlSerializer? - PullRequest
5 голосов
/ 29 октября 2011

У меня есть следующая структура XML. Элемент theElement может содержать элемент theOptionalList или нет:

<theElement attrOne="valueOne" attrTwo="valueTwo">
    <theOptionalList>
        <theListItem attrA="valueA" />
        <theListItem attrA="anotherValue" />
        <theListItem attrA="stillAnother" />
    </theOptionalList>
</theElement>
<theElement attrOne="anotherOne" attrTwo="anotherTwo" />

Что такое чистый способ выражения соответствующей структуры класса?

Я почти уверен в следующем:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace MyNamespace
{
    public class TheOptionalList
    {
        [XmlAttributeAttribute("attrOne")]
        public string AttrOne { get; set; }

        [XmlAttributeAttribute("attrTwo")]
        public string AttrTwo { get; set; }

        [XmlArrayItem("theListItem", typeof(TheListItem))]
        public TheListItem[] theListItems{ get; set; }

        public override string ToString()
        {
            StringBuilder outText = new StringBuilder();

            outText.Append("attrOne = " + AttrOne + " attrTwo = " + AttrTwo + "\r\n");

            foreach (TheListItem li in theListItems)
            {
                outText.Append(li.ToString());
            }

            return outText.ToString();
        }
    }
}

А также:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace MyNamespace
{
    public class TheListItem
    {
        [XmlAttributeAttribute("attrA")]
        public string AttrA { get; set; }

        public override string ToString()
        {
            StringBuilder outText = new StringBuilder();

            outText.Append("  attrA = " + AttrA + "\r\n");                
            return outText.ToString();
        }
    }
}

Но как насчет theElement? Должен ли я принять элемент theOptionalList в качестве типа массива, чтобы он прочитал то, что он находит в файле (или ничего, или один), а затем проверил в коде, есть ли он или нет? Или есть другой декоратор, который я могу поставить? Или это просто работает?

РЕДАКТИРОВАТЬ: Я закончил с использованием информации от этот ответ .

Ответы [ 3 ]

6 голосов
/ 29 октября 2011

Попробуйте добавить IsNullable = true к атрибуту XmlArrayItem.

4 голосов
/ 29 октября 2011

Похоже, что вы можете использовать другой тип bool, чтобы указать, включать элемент или нет.

Другой вариант - использовать специальный шаблон для создания логического поля, распознаваемого XmlSerializer, и для примененияXmlIgnoreAttribute для поля.Шаблон создается в виде propertyNameSpecified.Например, если есть поле с именем «MyFirstName», вы также должны создать поле с именем «MyFirstNameSpecified», которое инструктирует XmlSerializer, генерировать ли элемент XML с именем «MyFirstName».Это показано в следующем примере.

public class OptionalOrder
{
    // This field should not be serialized 
    // if it is uninitialized.
    public string FirstOrder;

    // Use the XmlIgnoreAttribute to ignore the 
    // special field named "FirstOrderSpecified".
    [System.Xml.Serialization.XmlIgnoreAttribute]
    public bool FirstOrderSpecified;
}

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

0 голосов
/ 11 февраля 2018

Дополнительно к свойству XxySpecifed существует также метод с префиксом ShouldSerialize

[XmlElement]
public List<string> OptionalXyz {get; set;}

public bool ShouldSerializeOptionaXyz() {
    return OptionalXyz != null && OptionalXyz.Count > 0 ;
}
...