Получение XML-раздела CDATA с помощью Linq

#c# #xml #linq

#c# #xml #linq

Вопрос:

Я искал способы добраться до текстовой области раздела CDATA и нашел очень удобные решения с использованием linq. Мне нужно извлечь XML, вложенный в раздел CDATA, чтобы я мог извлекать разные фрагменты информации. У меня есть следующий XML:

 <Envelope>
 <Warehouse />
 <Payload>
  - <![CDATA[ 
    <?xml version="1.0"?>
    <ROOT>
      <ORDERID>399798</ORDERID>
      <PRODUCTNUMBER>00003997</PRODUCTNUMBER>
      <DESCIPTION>Red Rider BB-Gun</DESCIPTION>
      <STATUS>InStock</STATUS>
      <LOCATION>Chicago</LOCATION>
    </ROOT> ]]>
 </Payload>
</Envelope>
  

Поэтому я хотел бы, если возможно, сделать это, извлекая весь раздел cdata в XDocument, чтобы я мог использовать Linq для запроса. Также, если бы я просто хотел извлечь один элемент из раздела CData. Как я могу это сделать? Использование Linq?

Я пытался использовать этот приведенный ниже код Linq, чтобы вернуть мне раздел cdata, но ничего не могу с ним поделать, поскольку он возвращается как IEnumerable . Вероятно, я упускаю что-то простое, поэтому я обращаюсь к мастерам Linq за помощью.

Вот код, о котором я упоминал:

  var queryCDATAXML = from el in xdoc.DescendantNodes()
                     where el.NodeType == XmlNodeType.CDATA
                     select el.Parent.Value.Trim();
  

Есть ли способ сделать выбор нового XDocument или XmlDocument следующим образом:

 //This doesn't compile.
 var queryCDATAXML = from el in xdoc.DescendantNodes()
                            where el.NodeType == XmlNodeType.CDATA
                            select new XDocument()
                              {  
                                 el.Parent.Value.Trim();
                              }   
  

Если я все делаю неправильно или это лучший способ добиться этого, я открыт для предложений. 🙂

Спасибо, DND

Обновление кода:

 var queryCDATAXML = from el in xdoc.DescendantNodes()
                     where el.NodeType == XmlNodeType.CDATA
                     select el.Parent.Value.Trim();

var xdoc = XDocument.Parse(queryCDATAXML);
  

Генерирует эту ошибку:
Аргумент ‘1’: невозможно преобразовать из ‘System.Коллекции.Общий.IEnumerable’ в ‘string’.

Комментарии:

1. В вашем последнем обновлении queryCDATAXML содержит список всех узлов CDATA в документе. Если вы знаете, что существует только один, вы можете использовать Single() : XDocument.Parse(queryCDATAXML.Single()) .

Ответ №1:

Вместо new XDocument этого попробуйте XDocument.Parse

 var queryCDATAXML = // get the value
var xdoc = XDocument.Parse(queryCDATAXML);
  

Вы получаете some Enumerable<string> , а не than string , поэтому вам нужно просто получить единственное значение.

 var node = xdoc.DescendantNodes().Single(el => el.NodeType == XmlNodeType.CDATA);
var content = node.Parent.Value.Trim();
var xdoc = XDocument.Parse(content);
  

Комментарии:

1. Пробовал, но проблема с типом — аргумент ‘1’: не удается преобразовать из ‘System. Коллекции. Общий. IEnumerable<string>’ в ‘string’ . Есть предложения?

2. @DotNetDude, это зависит от вашего конкретного кода. У нас нет хрустальных шаров, чтобы увидеть это, вы должны показать это нам.

3. @svick, я обновил код, чтобы отразить идею Кирка и, в конечном счете, ошибку, которую я получаю. Есть идеи?

4. @DotNetDude Я обновил свой ответ для вас — это потому select , что возвращает коллекцию (IEnumerable), а не одну строку. Попробуйте обновленный код.

Ответ №2:

Я решил этот случай в такой форме:

 XDocument xdoc = XDocument.Parse(vm.Xml);

XNamespace cbc = @"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2";
  var list2 =
       (from el in xdoc.Descendants(cbc   "Description")
        select el).FirstOrDefault();

      var queryCDATAXML = (from eel in list2.DescendantNodes()                                                
      select eel.Parent.Value.Trim()).FirstOrDefault();
  

Я надеюсь, что они помогут