Очищает элемент Xml с помощью атрибута "nil = true" - Создать версию linq? - PullRequest
0 голосов
/ 10 февраля 2012

Я пытаюсь очистить элемент Xml с помощью атрибута "nil = true" внутри документа. Я придумываю этот алгоритм, но мне не нравится, как он выглядит.

Кто-нибудь знает версию этого алгоритма на linq?

    /// <summary>
    /// Cleans the Xml element with the attribut "nil=true".
    /// </summary>
    /// <param name="value">The value.</param>
    public static void CleanNil(this XElement value)
    {
        List<XElement> toDelete = new List<XElement>();

        foreach (var element in value.DescendantsAndSelf())
        {
            if (element != null)
            {
                bool blnDeleteIt = false;
                foreach (var attribut in element.Attributes())
                {
                    if (attribut.Name.LocalName == "nil" && attribut.Value == "true")
                    {
                        blnDeleteIt = true;
                    }
                }
                if (blnDeleteIt)
                {
                    toDelete.Add(element);
                }
            }
        }

        while (toDelete.Count > 0)
        {
            toDelete[0].Remove();
            toDelete.RemoveAt(0);
        }
    }

Ответы [ 4 ]

1 голос
/ 10 февраля 2012

Что такое пространство имен атрибута nil? Поместите это внутрь {} так:

public static void CleanNil(this XElement value)
{
    value.Descendants().Where(x=> (bool?)x.Attribute("{http://www.w3.org/2001/XMLSchema-instance}nil") == true).Remove();
}
0 голосов
/ 23 марта 2012

Я изменяю свой способ решения этой проблемы и избегаю создания nil для моего типа nullable Я использую следующее

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer%28v=vs.90%29.aspx

    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;
    }
0 голосов
/ 10 февраля 2012

Метод расширения:

public static class Extensions
{
    public static void CleanNil(this XElement value)
    {
        value.DescendantsAndSelf().Where(x => x.Attribute("nil") != null && x.Attribute("nil").Value == "true").Remove();
    }
}

Пример использования:

File.WriteAllText("test.xml", @"
                <Root nil=""false"">
                    <a nil=""true""></a>
                    <b>2</b>
                    <c nil=""false"">
                        <d nil=""true""></d>
                        <e nil=""false"">4</e>
                    </c>
                </Root>");
var root = XElement.Load("test.xml");
root.CleanNil();
Console.WriteLine(root);

Выход:

<Root nil="false">
  <b>2</b>
  <c nil="false">
    <e nil="false">4</e>
  </c>
</Root>

Как видите, узлы <a> и <d> были удалены, как и ожидалось. Единственное, на что следует обратить внимание, это то, что вы не можете вызвать этот метод на узле <Root>, поскольку корневой узел не может быть удален, и вы получите эту ошибку времени выполнения:

Родитель отсутствует.

0 голосов
/ 10 февраля 2012

Это должно работать ..

public static void CleanNil(this XElement value)
{
     var todelete = value.DescendantsAndSelf().Where(x => (bool?) x.Attribute("nil") == true);
     if(todelete.Any())
     {
        todelete.Remove();
     }
}
...