2013-06-06 2 views
2

Мне нужно удалить XElement из XDocument.Удалить XElement из другого XDocument

Проблема в том, что я не могу просто использовать .Remove(), потому что мой XDocument - это не то же самое, что и XElement.

Очень важный факт - производительность.

Сценарий: У меня есть XDocument docSource, и я копирую его до XDocument doc. Я выбираю узел docSource и хочу удалить этот узел в моем doc.

До сих пор я использую этот обходной путь (который также может удалить некоторые неправильные узлы, если они получили такое же название родительского, но это не имеет значения до сих пор):

private static XNode actualNode; 
    private static void RemoveNode(XDocument doc) 
    { 
     doc.Root.Descendants(((XElement)actualNode).Name.LocalName) 
          .Where(e => actualNode.Parent.Name.LocalName.Equals(e.Parent.Name.LocalName)) 
          .Remove(); 
    } 

Есть ли лучший способ сделай это? И особенно более быстрый способ? Мой XDocument имеет 1000 строк.

ответ

3

Ну лучший способ сделать существующий подход на основе имен будет:

doc.Root.Descendants(actualNode.Parent.Name) 
     .Elements(actualNode.Name) 
     .Remove(); 

Помимо всего прочего, это проще - и не использует только локальное имя. (Если элементы фактически находятся в разных пространствах имен, вы должны учитывать это отдельно. IMO.)

Но это все еще просто использует «имя элемента и родительское имя» как способ идентификации элемента. У вас есть что-то еще, что более надежно идентифицирует элемент? Какой-то атрибут? Я предполагаю, что у вас есть представление о том, какой элемент вы найдете.

Мой XDocument имеет 1000 строк.

В любом случае, это должно быть моргание глаз. У вас есть какие-либо признаки того, что это вызывает проблемы с производительностью?

Другая вещь, чтобы рассмотреть:

Сценарий: У меня есть XDocument docSource и скопировать это XDocument док. Я выбираю узел docSource и хочу удалить этот узел в моем документе.

Есть ли причина, по которой вы не просто избегаете копирования узла для начала?

+0

Проблема с производительностью: Да, если я просто не использую этот единственный метод, то мое исполнение работает от 700 мс до 200 мс, поэтому эта линия потребляет огромную производительность. – WhileTrueSleep

+1

@WhileTrueSleep: Кажется немного странным, если это действительно всего 1000 строк. Это определенно не компиляция JIT и т. Д.? Я действительно не ожидал, что ваш текущий код вызовет проблему, хотя код, который я дал, может все равно работать лучше. –

+0

Вы правы, показанный код не был проблемой. В рекурсии был ошибочный подход, называемый методом 100.000 раз. – WhileTrueSleep

1

Как вы правильно сказали, если вы просто полагаетесь на имя родителя.Name.LocalName, вы можете в конечном итоге удалить неправильные дочерние узлы, если есть родители с похожими именами.

Если вы проверяете повторные родительские узлы перед удалением дочерних узлов, вы сможете решить эту проблему.

Вы должны иметь возможность добиться точности, загрузив узлы в массив/список. Затем вы сможете найти позицию точного родительского узла. Но я боюсь, что это не улучшит производительность.

Для примера у вас есть 3 родительских узла с «XZY». Пользователь выбирает 2 родительских узла.Таким образом, ваш родительский индекс будет равен 1 (при условии, что индекс начинается с 0) Таким образом, вы должны удалять только детей с родительским индексом 1.

Надеюсь, это поможет.

Смежные вопросы