Как удалить определенный элемент item из XML? C#

Не удаляется элемент, может проблема в пути? Пытался удалить по id элемента, но в данной грамматике, у элемента item нет атрибута id, пытаюсь удалить по атрибуту weight, но снова не выходит. На этот раз ошибок нет, но удалять он все равно не хочет, может проблема в пути к этому элементу? Помогите пожалуйста..

 <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE grammar[
  <!ELEMENT grammar ANY>
  <!ELEMENT rule ANY>
  <!ELEMENT one-of ANY>
  <!ELEMENT item ANY>
  <!ATTLIST grammar version CDATA #REQUIRED>
  <!ATTLIST grammar root CDATA #REQUIRED>
  <!ATTLIST grammar tag-format CDATA #REQUIRED>
  <!ATTLIST rule scope (public|private) #REQUIRED>
  <!ATTLIST rule id ID #REQUIRED>
  <!ATTLIST item id ID #IMPLIED>
]>
<grammar version="1.0" xml:lang="ru-RU" root="Подтверждение" xmlns="http://www.w3.org/2001/06/grammar" tag-format="semantics-ms/1.0">
    <rule>
       <one-of>
       </one-of>
    </rule>
    <rule xmlns="http://www.w3.org/2001/06/grammar" id="имя" scope="public">
        <one-of>
          <item>Иванов<tag> $ = "Иванов"</tag></item>
          <item weight="1.0" xmlns="http://www.w3.org/2001/06/grammar">Можаев<tag> $ = "Можаев" 
          </tag></item>
        </one-of>
      </rule>
</grammar>

static string grammarPathXML = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UserGrammar.xml");  //путь к XML    ​
XDocument xdoc = XDocument.Load(grammarPathXML);
       ​xdoc.Elements("rule").Where(att => att.Attribute("id").Value == "имя")
           ​.Elements("one-of")
           ​.Elements("item")
           ​.Where(att => att.Attribute("weight").Value == "1.0")
           ​.Remove();
       ​xdoc.Save(grammarPathXML);

Ответы (1 шт):

Автор решения: A K

Для начала я расскажу о инструменте, которым буду пользоваться во время ответа. Это Linqpad - легковесная мини-IDE для отладки небольших фрагментов кода.

Очень удобно смотреть небольшие запросы пользуясь методом расширения .Dump(): вот как выглядит ваш пример:

введите сюда описание изображения

Или например корневой элемент:

введите сюда описание изображения

Или первая нода:

введите сюда описание изображения

Или любой linq-запрос. Через некоторое время натренируетесь так, что будете из головы писать длинные linq-запросы без ошибок.


Ну и начнём разбирать ваш запрос с самого начала.

И в самом же начале видим, что ваш запрос не находит никаких нод rule:

введите сюда описание изображения

И всё, можно уже не искать никакую ошибку в коде далее, потому что уже НОЛЬ узлов, как их не фильтруй - ничего не найдёшь, новые не появятся. И вообще весь linq-код правильный, валидный, я проверил по структуре - всё верно. За одним исключением.

Вы не работаете с пространствами/неймспейсами XML. Прямо говоря -- типичная ошибка кто начинает работать с XML и особо документацию не читал.

Вот настоящее имя вашего элемента, вот так всё прекрасно находится:

введите сюда описание изображения

Взято из вашего же xml-файла:

введите сюда описание изображения

Ну, понятное дело так влоб никто не пишет. Если посмотрите оф.доку и примеры на stackoverflow (сходу что нашлось такое) то все используют переменную неймспейса:

введите сюда описание изображения

И постепенно двигайтесь в отладке вашего linq-запроса:

введите сюда описание изображения

И так шаг за шагом - до конца:

введите сюда описание изображения

Ну и финально -- удаляете и сохраняете:

введите сюда описание изображения

Всё!

Итого, на будущее, если хочется научиться разбираться самостоятельно, а не ждать помощи от коллег:

  • научитесь отлаживать запрос шаг за шагом и находить первую точку в которой уже не работает;
  • мало кто любит читать документацию и фундаментальные книги, особенно когда тебе презентуют технологию "хей, тут три строчки кода написать" (наша технология крутая и подходит для быстрого старта). За этот быстрый старт платят именно тем, что когда начинаются проблемы - надо лезть в доки, которые никто не хочет читать.
→ Ссылка