Чтение текстового содержимого из XElement

Как в .NET прочитать текстовое содержимое из XЭлемент?

Например, из XElement

XElement.Parse("<tag>Alice &amp; Bob<other>cat</other></tag>")

Я хотел бы строку «Алиса и Боб»


Я пробовал element.Value, но это возвращает "Алиса и Рысь" :(


person Colonel Panic    schedule 15.10.2012    source источник
comment
Я почти уверен, что это плохо сформированный XML, поэтому у вас возникла проблема. Теги должны содержать либо значение, либо другие теги, но не оба.   -  person Bobson    schedule 15.10.2012
comment
На самом деле HTML — это не XML, и наоборот. Они связаны, конечно, но только XHTML является и тем, и другим. en.wikipedia.org/wiki/XHTML. Если вы собираетесь анализировать HTML, вам следует использовать парсер HTML. Если вы анализируете XML, я все еще думаю, что это плохо сформировано.   -  person Bobson    schedule 15.10.2012
comment
Я не уверен, изменился ли стандарт за это время, но это хорошо сформированный XML по текущему стандарту. Узел tag имеет два дочерних узла, один текстовый узел и один элементный узел. Проблема усложняется с DTD или схемами, и в этом случае может быть невозможно точно указать такой формат.   -  person GrandOpener    schedule 05.04.2017
comment
@Bobson: это действительный xml, поэтому вы не можете указывать плохо сформированный xml только потому, что считаете это плохой практикой.   -  person VikciaR    schedule 01.02.2020


Ответы (4)


Просто потому, что у меня недавно было подобное требование, я предлагаю:

var x = XElement.Parse("<tag>Alice &amp; Bob<other>cat</other></tag>")
var text = string.Concat(x.Nodes().OfType<XText>().Select(t => t.Value));

Не захватывает текстовое содержимое дочерних узлов, но объединяет все непомеченные текстовые узлы в текущем элементе.

person jimbobmcgee    schedule 26.05.2017
comment
Это самый гибкий\общий и поэтому полезный ответ. - person mutex; 04.07.2017
comment
Это, но без concat это здорово. Concat просто объединит строки и сделает результат неоднозначным. - person user420667; 08.03.2018

Попробуйте следующий код. Это может вам помочь.

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            var parent = XElement.Parse("<tag>Alice &amp; Bob<other>cat</other></tag>");
            var nodes = from x in parent.Nodes()
                            where x.NodeType == XmlNodeType.Text
                            select (XText)x;

            foreach (var val in nodes)
            {
                Console.WriteLine(val.Value);
            }
            Console.ReadLine();
        }
    }
}
person MMK    schedule 15.10.2012

Используя element.FirstNode, вы можете получить необработанный контент, который у вас есть внутри элемента «Алиса и Боб», поэтому вам нужно только «отключить экранирование» амперсанда, и вы получите ожидаемый результат.

person Ricardo Rodriguez    schedule 15.10.2012

person    schedule
comment
попробуйте использовать эту строку s = System.Web.HttpUtility.HtmlDecode((string.Format(t.FirstNode.ToString()))); Убедитесь, что имеется ссылка на System.Web Dll. - person MMK; 15.10.2012
comment
вы также можете использовать это string s = System.Net.WebUtility.HtmlDecode((string.Format(t.FirstNode.ToString()))); - person MMK; 15.10.2012
comment
но это тоже работает. Экранированные специальные символы не являются причиной для понижения голоса. - person Martin Schneider; 13.07.2016