Каков наиболее эффективный способ найти и установить значения элементов в XDocument?

Учитывая следующий XML-шаблон:

<Request module="CRM" call="list_service_features" id="{ID}">
  <block name="auth">
     <a name="username" format="text">{USERNAME}</a>
     <a name="password" format="password">{PASSWORD}</a>
     <a name="client-id" format="counting">{CLIENT-ID}</a>
  </block>
  <a name="service-id" format="counting">{SERVICE-ID}</a>
</Request>

Используя XDocument, как лучше всего установить значения в фигурных скобках. Я дошел до сих пор, но застрял на наилучшем способе выбора каждого из трех узлов <a /> внутри элемента <block/>. Это всего лишь небольшой фрагмент XML, в других может быть до 20 элементов <a name="..."></a>.

То, как построен XML, не было моим творением, это то, что мы должны отправить в «веб-службу» нашего поставщика... прежде чем кто-нибудь посмеется над атрибутом format="counting" :)

@David - спасибо за ответ, спасибо. Я как бы надеялся, что это будет немного более элегантно, вроде как:

List<XElement> e = doc.Descendants("a").ToList();
e.Where(x => x.Attributes("name") == "username").Single().Value = "abc";
e.Where(x => x.Attributes("name") == "password").Single().Value = "abc";

Очевидно, что приведенный выше код не работает, но я подумал, что для каждого из тегов <a> будет элегантная строчка.


person Kev    schedule 18.11.2008    source источник


Ответы (1)


Это делает это для вас? Старая добрая собственность Потомков.

string xmlInput = ...;
XDocument myDoc = XDocument.Parse(xmlInput);
//
List<XElement> someElements = myDoc.Descendants("a").ToList();
someElements.ForEach(x => x.Value = "Foo");
//
Console.WriteLine(myDoc);

Хм, я вижу, у тебя там есть атрибут. Можно и так:

string xmlInput = //...
XDocument myDoc = XDocument.Parse(xmlInput);
//
List<XText> someText =
  myDoc.Descendants()
  .Nodes()
  .OfType<XText>()
  .Where(x => x.Value.StartsWith("{") && x.Value.EndsWith("}"))
  .ToList();
//
List<XAttribute> someAttributes =
  myDoc.Descendants()
  .Attributes()
  .Where(x => x.Value.StartsWith("{") && x.Value.EndsWith("}"))
  .ToList();
//
someText.ForEach(x => x.Value = "Foo");
someAttributes.ForEach(x => x.Value = "Bar");
//
Console.WriteLine(myDoc);

Ах, теперь с тем, что вы ожидаете, я заставлю это работать:

List<XElement> e = myDoc.Descendants("a").ToList();
e.Where(x => x.Attribute("name").Value == "username").Single().Value = "abc";
e.Where(x => x.Attribute("name").Value == "password").Single().Value = "abc";
person Amy B    schedule 18.11.2008
comment
Да, это то, что я ищу. Я пришел к чему-то похожему, но более неуклюжему: e.Attributes(name).Where(a => a.Value == username).Single().Parent.Value = abcdef; Очень признателен! - person Kev; 18.11.2008