【问题标题】:Retrieve full string of XElement with mixed content检索具有混合内容的完整 XElement 字符串
【发布时间】:2013-02-23 04:47:00
【问题描述】:

假设我在 XElement 对象中有以下内容

<root>Hello<child>Wold</child></root>

如果我使用XElement.ToString(),这给了我

"<root xmnls="someschemauri">Hello<child>World</child></root>"

如果我使用 XElement.Value,我会得到

"Hello World"

我需要得到

"Hello <child>World</child>"

执行此操作的正确功能是什么(如果有的话)?

【问题讨论】:

  • 您使用的是哪个版本的 .NET? .NET 4.0 及更高版本的答案不同。

标签: c# xml .net-3.5 linq-to-xml


【解决方案1】:

扩展方法基于最快知道的解决方案:

public static class XElementExtension
{
    public static string InnerXML(this XElement el) {
        var reader = el.CreateReader();
        reader.MoveToContent();
        return reader.ReadInnerXml();
    }
}

然后简单地调用它:xml.InnerXML();

【讨论】:

    【解决方案2】:

    我没有时间测试这个,但是试试:

    var inners = from n in xelementVariableName.Nodes()
                           select n;
    return String.Join(String,Empty, inners);
    

    测试:

    public static string ReturnInnerXml()
    {
        var doc = XDocument.Parse(@"<root>Hello<child>World</child></root>");
        var root = doc.Root;
        if (root == null)
        {
            throw new InvalidOperationException("No root");
        }
    
        var inners = from n in root.Nodes()
                     select n;
        return String.Join(String.Empty, inners);
    }
    

    这会产生:

    Hello<child>World</child>
    

    使用 .NET 4.0。

    【讨论】:

    • 我假设你的意思是: var inners = from element in xElement.Nodes() select element.ToString();return inners.Aggregate((content, next) => next + " " + 内容);遗憾的是它返回包含的根标签
    【解决方案3】:

    .NET 4 的解决方案

    var result = String.Join("", rootElement.Nodes()).Trim();
    

    完整代码(适用于 .NET 3.5):

    XElement rootElement = XElement.Parse("<root>Hello<child>Wold</child></root>");
    var nodes = rootElement.Nodes().Select(n => n.ToString()).ToArray();
    string result = String.Join("", nodes).Trim();
    Console.WriteLine(result);
    // writes "Hello<child>World</child>"
    

    无需加入所有节点的快速解决方案:

    XElement rootElement = XElement.Parse("<root>Hello<child>Wold</child></root>");
    var reader = rootElement.CreateReader();
    reader.MoveToContent();
    string result = reader.ReadInnerXml(); 
    

    【讨论】:

    • @Magnum 你做错了什么。不应该有bee根节点本身。仅连接节点。
    • 我得到的rootElement是从XDocument.Root property.派生的,所以我只是做了String.Join("", xDoc.Root.Nodes()).Trim();上述输出就是我得到的。
    • @Magnum 那么你的&lt;root&gt; 元素不是文档的Root。请选择您的 &lt;root&gt; 元素
    • xElement.Nodes() 不返回字符串数组,我不能在 String.Join 函数中使用它。我在 .NET 3.5 顺便说一句
    • @Machinegon on .NET 4 String.Join 与 IEnumerable 一起使用。顺便说一句,在 .NET 3.5 上调用 .ToArray()
    【解决方案4】:

    这里是:

    var element = XElement.Parse("<root>Hello<child>Wold</child></root>");
    string xml = string.Join("", element.Nodes().Select(e => e.ToString()).ToArray());
    

    返回 Hello&lt;child&gt;Wold&lt;/child&gt; 并适用于 .NET 3.5

    【讨论】:

    • 它与我的答案有何不同?
    【解决方案5】:

    这样就可以了:

    var element = XElement.Parse("<root>Hello<child>Wold</child></root>");
    string xml = string.Join("", element.Nodes().Select(e => e.ToString()));
    

    对于 .NET 3.5(如果这是问题的重点):

    var element = XElement.Parse("<root>Hello<child>Wold</child></root>");
    string xml = string.Join("", element.Nodes().Select(e => e.ToString()).ToArray());
    

    【讨论】:

    • 这将返回"Hello&lt;child&gt;Wold&lt;/child&gt;Wold",并带有不必要的Wold 和结尾。
    • 已修复 - Nodes(),而不是 DescendandNodes()。
    • 同样的问题 - 它与我的答案有何不同?
    • 你的第一条/主线有点笨拙。为什么修剪?并且在 .NET 3.5 中不起作用。你后来也修好了。
    • @Nenad 第一行是在 OP 提到 3.5 之前写的(见时间线)。这就是为什么下面的代码是固定的。非单行 xml 需要修剪。否则你会在开始和结束时得到空行。
    【解决方案6】:

    这很好用:

    //SOLUTION BY Nenad
    var element = XElement.Parse("<root>Hello<child>World</child></root>");
    string xml = string.Join("", element.DescendantNodes().Select(e => e.ToString()));
    Debug.WriteLine(xml);
    

    最终输出:Hello&lt;child&gt;Wold&lt;/child&gt;World


    尝试#3

    XDocument xDoc = XDocument.Parse(@"<root>Hello<child>World</child></root>");
    XElement rootElement = xDoc.Root;
    Debug.WriteLine(rootElement.Value + rootElement.FirstNode.ToString());
    

    【讨论】:

    • 或者.Nodes.ToString()?
    • @JohnSaunders 我想过,但他的例子非常简单,所以节点会返回子节点,不一定是 cmets 或者不是?由于我不知道他最终的 xml 文件会是什么样子,所以我使用了 Descendants。
    • 不,不是这样,它 Nodes() 和 Descendant() 给了我一些奇怪的东西,比如 System.Xml.Linq.XContainer+d__a System.Xml.Linq.XContainer+d__a 而不是标签和值 System.Xml.Linq.XContain
    • 但是,后代会返回文本吗?
    • 不,它没有,它显然返回 XElement 的集合。
    猜你喜欢
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 2016-06-22
    • 1970-01-01
    • 2019-09-10
    相关资源
    最近更新 更多