Делать это с помощью текстового поиска и замены должно быть сделано с помощью StringBuilder
, чтобы избежать нормальных проблем создания строк в цикле (много мусора). Это также очень трудно предотвратить ложные срабатывания (что, если текст, соответствующий атрибут происходит в текстовом узле?)
лучших вариантов, с различными компромиссами включают в себя:
- нагрузки в XDocument или XmlDocument, перебирать дерево заменяет соответствующие атрибуты.
- Использование XSLT
- Прочтите XmlReader и напишите непосредственно в XmlWriter с измененными атрибутами.
Из этих # 3 можно избежать загрузки всего документа в память. # 2 требует навыков XSLT, но легко позволяет произвольное количество замен (ядром XSLT может быть шаблон, с новыми, старыми парами атрибутов, введенными во время выполнения). # 1, вероятно, будет проще, но с целым документом в памяти и накладными расходами на обработку нескольких замен.
Я бы скорее посмотрел на XSLT с использованием Xml Reader/Writer в качестве резервной копии.
Однако # 1 должно быть проще реализовать, что-то вроде (игнорирование XML пространства имен среди других деталей):
using System.Xml.Linq;
using System.Xml.XPath;
var xdoc = XDocument.Load(....);
var nav = xdoc.CreateNavigator();
foreach (repl in replacements) {
var found = (XPathNodeIterator) nav.Evaluate("//@" + repl.OldName);
while (found.MoveNext()) {
var node = found.Current;
var val = node.Value;
node.DeleteSelf(); // Moves ref to parent.
node.CreateAttribute("", repl.NewName, "", val);
}
}
Окончательный выбор будет зависеть от балансировки производительности (особенно памяти при работе с большими документами) и сложность , но только вы (и ваша команда) можете сделать этот звонок.
Хороший вопрос (+1). См. Мой ответ для полного решения XSLT - возможно, одного из самых простых. –