Удалите элемент xml с помощью xsi: nil = "true" C # сериализация - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть XML, который имеет некоторые значения, и иногда могут быть нулевые значения, как показано ниже: Я не хочу, чтобы узлы с нулевым значением вообще указывались в XML! Элементы установлены IsNullable = true в классе. Любые предложения, как я перепробовал много вещей в Google .. ничего не помогло!

<?xml version="1.0" encoding="utf-8"?>
<Materials>
  <Material>
    <MaterialName>ABC</MaterialName>
    <Weight Value="0.303">
      <Weight_A xsi:nil="true" />
      <Weight_B xsi:nil="true" />
    </Weight>
    <Density Value="800">
      <Density_A xsi:nil="true" />
      <Density_B xsi:nil="true" />
    </Density>
    <Volume Value="8771.427" />
  </Material>
  <Material>
    <MaterialName>ABC</MaterialName>
    <Weight>
      <V5_Weight>2.009</V5_Weight>
      <V6_Weight>1.3318154561904</V6_Weight>
    </Weight>
    <Density>
      <V5_density>1000</V5_density>
      <V6_density>663</V6_density>
    </Density>
    <Volume Value="2008771.427" />
  </Material>
</Materials>

Структура класса выглядит следующим образом:

[XmlRoot(ElementName = "Weight")]
public class Weight
{
    [XmlElement(ElementName = "Weight_A", IsNullable = true)]
    public string Weight_A { get; set; }

    [XmlElement(ElementName = "Weight_B", IsNullable = true)]
    public string Weight_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }

}

[XmlRoot(ElementName = "Density")]
public class Density
{
    [XmlElement(ElementName = "Density_A", IsNullable = true)]
    public string Density_A { get; set; }
    [XmlElement(ElementName = "Density_B", IsNullable = true)]
    public string Density_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Volume")]
public class Volume
{
    [XmlElement(ElementName = "Volume_A")]
    public string Volume_A { get; set; }
    [XmlElement(ElementName = "Volume_B")]
    public string Volume_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Material")]
public class Material
{
    [XmlElement(ElementName = "MaterialName")]
    public string MaterialName { get; set; }
    [XmlElement(ElementName = "Weight")]
    public Weight Weight { get; set; }

    [XmlElement(ElementName = "Density")]
    public Density Density { get; set; }
    [XmlElement(ElementName = "Volume")]
    public Volume Volume { get; set; }
}

[XmlRoot(ElementName = "Materials")]
public class Materials
{
    [XmlElement(ElementName = "Material")]
    public List<Material> Material { get; set; }
}

1 Ответ

0 голосов
/ 14 сентября 2018

Основная проблема в том, что вы установили XmlElementAttribute.IsNullable = true.Из документов :

Получает или задает значение, указывающее, должен ли XmlSerializer сериализовать элемент, для которого установлено значение null, в качестве пустого тега.с атрибутом xsi:nil, установленным в значение true.

Таким образом, теоретически вы можете просто установить его в значение false (или не устанавливать его вообще) и xsi:nil атрибуты не будут выдаваться для нулевых значений:

[XmlRoot(ElementName = "Weight")]
public class Weight
{
    [XmlElement(ElementName = "Weight_A" /*, IsNullable = true*/)]
    public string Weight_A { get; set; }
    [XmlElement(ElementName = "Weight_B" /*, IsNullable = true*/)]
    public string Weight_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Density")]
public class Density
{
    [XmlElement(ElementName = "Density_A"/*, IsNullable = true*/)]
    public string Density_A { get; set; }
    [XmlElement(ElementName = "Density_B"/*, IsNullable = true*/)]
    public string Density_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

Однако, если вы это сделаете, вы можете столкнуться с проблемой десериализации старых XML-файлов, а именно, что строковые элементы xsi:nil теперь будут десериализованы какпустые строки вместо null строк.(Демонстрационная скрипка # 1 здесь .) Если это становится проблемой, вы должны оставить настройку XmlElementAttribute.IsNullable = true и вместо этого использовать один из шаблонов условной сериализации, описанных в этого ответа to ShouldSerialize * () vs * Указанный шаблон условной сериализации :

[XmlRoot(ElementName = "Weight")]
public class Weight
{
    [XmlElement(ElementName = "Weight_A", IsNullable = true)]
    public string Weight_A { get; set; }

    public bool ShouldSerializeWeight_A() { return Weight_A != null; }

    [XmlElement(ElementName = "Weight_B", IsNullable = true)]
    public string Weight_B { get; set; }

    public bool ShouldSerializeWeight_B() { return Weight_B != null; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Density")]
public class Density
{
    [XmlElement(ElementName = "Density_A", IsNullable = true)]
    public string Density_A { get; set; }

    public bool ShouldSerializeDensity_A() { return Density_A != null; }

    [XmlElement(ElementName = "Density_B", IsNullable = true)]
    public string Density_B { get; set; }

    public bool ShouldSerializeDensity_B() { return Density_B != null; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

После этого элементы <NodeName xsi:nil="true" /> будут отображены в строку null во времядесериализации и полностью пропущены во время сериализации.

Примечания:

  • Ваш XML не правильно сформирован.В нем отсутствует определение префикса пространства имен xsi:, возможно, потому что это фрагмент какого-то более крупного документа.Этот ответ предполагает, что оно должно быть:

    <Materials 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
  • Некоторые элементы вообще не связаны с вашей моделью данных c #, включая:

    <V5_Weight>2.009</V5_Weight>
    <V6_Weight>1.3318154561904</V6_Weight>
    

    И

    <V5_density>1000</V5_density>
    <V6_density>663</V6_density>
    

    Этот ответ не пытается решить эту проблему (если она действительно является проблемой).

Пример скрипта № 2 здесь .

...