Выполнение этого с текстовым поиском и заменой должно выполняться с использованием 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);
}
}
Окончательный выбор будет зависеть от производительности балансировки (особенно памяти при работе с большими документами) и сложности. но только вы (и ваша команда) можете сделать этот звонок.