Проблема с XML — HTML в узле удаляется (ASP.NET C # LINQ to XML)

#c# #xml #linq-to-xml #xelement

#c# #xml #linq-to-xml #xelement

Вопрос:

Когда я загружаю этот XML-узел, HTML внутри узла полностью удаляется.

Это код, который я использую для получения значения внутри узла, которое представляет собой текст, объединенный с HTML:

 var stuff = innerXml.Descendants("root").Elements("details").FirstOrDefault().Value;
  

Внутри узла «подробности» находится текст, который выглядит следующим образом:

 "This is <strong>test copy</strong>. This is <a href="#">A Link</a>"
  

Когда я смотрю в «stuff» var, я вижу это:

 "This is test copy. This is A Link". There is no HTML in the output... it is pulled out.
  

Возможно, значение должно быть InnerXml или innerHTML? Имеет ли FirstOrDefault () какое-либо отношение к этому?

Я не думаю, что xml нуждается в блоке «cdata»…

Вот более полный фрагмент кода:

  announcements =
                from link in xdoc.Descendants(textContainer).Elements(textElement)
                where link.Parent.Attribute("id").Value == Announcement.NodeId
                select new AnnouncmentXml
                {
                    NodeId = link.Attribute("id").Value,
                    InnerXml = link.Value
                };

XDocument innerXml;
innerXml = XDocument.Parse(item.InnerXml);
var abstract = innerXml.Descendants("root").Elements("abstract").FirstOrDefault().Value;
  

Наконец, вот фрагмент Xml-узла. Обратите внимание, что в стандартной структуре xml присутствует «InnerXml». Это начинается с . Я называю это «InnerXml», и это то, что я передаю в XDocument под названием InnerXml:

  <text id="T_403080"><root> <title>How do I do stuff?</title> <details> Look Here <a href="http://" target=" _blank">Some Form</a>. Please note that lorem ipsum dlor sit amet.</details> </root></text> 
  

[ОБНОВИТЬ]

Я пытался использовать этот вспомогательный lamda, и он вернет HTML, но он экранирован, поэтому, когда он отображается на странице, я вижу фактический HTML в представлении (он показывает вместо ссылки, тег выводится на экран:

 Title = innerXml.Descendants("root").Elements("title").FirstOrDefault().Nodes().Aggregate(new System.Text.StringBuilder(), (sb, node) => sb.Append(node.ToString()), sb => sb.ToString());
  

Итак, я попробовал как HtmlEncode, так и HtmlDecode, но ни то, ни другое не помогло. Один показал экранированные символы на экране, а другой ничего не сделал:

 Title = 
                        System.Web.HttpContext.Current.Server.HtmlDecode(
                            innerXml.Descendants("root").Elements("details").Nodes().Aggregate(new System.Text.StringBuilder(), (sb, node) => sb.Append(node.ToString()), sb => sb.ToString())
                        );
  

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

1. Value Свойство предоставляет вам строковое значение, а не какую-либо разметку. Ваш агрегированный подход выглядит правильным, если вы хотите разметку любых дочерних узлов в виде строки. Если использование этого не дает вам желаемого результата в вашем ASP.NET контекст затем вам нужно более подробно объяснить, как вы его используете. Итак, что вы делаете с тем, Title с помощью Nodes().Aggregate(new System.Text.StringBuilder(), (sb, node) => sb.Append(node.ToString()), sb => sb.ToString()) чего вы создаете?

Ответ №1:

В итоге я использовал XmlDocument вместо XDocument. Не похоже, что LINQ to XML достаточно развит, чтобы поддерживать то, что я пытаюсь сделать. У XDoc нет свойства InnerXml, только Значение.

Может быть, когда-нибудь я смогу вернуться к LINQ. На данный момент мне просто нужно было избавиться от этого со своей тарелки. Вот мое решение:

 // XmlDoc to hold custom Xml within each node
        XmlDocument innerXml = new XmlDocument();
        try
        {
            // Parse inner xml of each item and create objects
            foreach (var faq in faqs)
            {
                innerXml.LoadXml(faq.InnerXml);

                FAQ oFaq = new FAQ();

                #region Fields
                // Get Title value if node exists and is not null
                if (innerXml.SelectSingleNode("root/title") != null)
                {
                    oFaq.Title = innerXml.SelectSingleNode("root/title").InnerXml;
                }

                // Get Details value if node exists and is not null
                if (innerXml.SelectSingleNode("root/details") != null)
                {
                    oFaq.Description = innerXml.SelectSingleNode("root/details").InnerXml;
                }
                #endregion

                result.Add(oFaq);
            }
        }
        catch (Exception ex)
        {
            // Handle Exception
        } 
  

Ответ №2:

Я действительно думаю, что перенос вашего узла details в блок cdata является правильным решением. CData в основном указывает, что информация, содержащаяся в нем, должна обрабатываться как текст, а не анализироваться на наличие специальных символов XML. Символы html в узле details, особенно < и >, находятся в прямом конфликте со спецификацией XML и действительно должны быть помечены как текст.

Вы могли бы обойти это, взяв InnerXml, но если у вас есть контроль над содержимым документа, cdata является правильным решением.

На случай, если вам нужен пример того, как это должно выглядеть, вот модифицированная версия узла detail:

 <details>
    <![CDATA[
         This is <strong>test copy</strong>. This is <a href="#">A Link</a>
    ]]>
</details>
  

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

1. Спасибо за ваш ответ, Эван. У меня нет доступа к этому XML, это было бы неплохо — тогда я бы добавил блок CDATA. По-видимому, это работало с более старой версией XPATH без cdata, поэтому я должен быть в состоянии заставить ее отображать HTML. Моя проблема сейчас в том, что у меня нет доступа к свойству InnerXml. Когда я пытаюсь InnerXml. Потомки («корень»). Элементы («абстрактные»). FirstOrDefault(). InnerXml это не работает (очевидно, InnerXml не является свойством XElement). Значение — это единственный способ доступа, который я вижу в intellisense. Есть другие идеи? : /

2. Этот пост 10-летней давности мне очень помог, спасибо!

3. Так рад это слышать. По иронии судьбы, я давно забыл о cdata и xml в целом. :-).