C# 使用LINQ将XML标记集合连接到字符串
我一直在使用一个我无法控制的web服务,并试图将该服务返回的XML解析为一个标准对象 XML结构的一部分如下所示C# 使用LINQ将XML标记集合连接到字符串,c#,linq,linq-to-xml,C#,Linq,Linq To Xml,我一直在使用一个我无法控制的web服务,并试图将该服务返回的XML解析为一个标准对象 XML结构的一部分如下所示 <NO> <L>Some text here </L> <L>Some additional text here </L> <L>Still more text here </L> </NO> 这里有一些文字 这里有一些附加文本 这里还有更多的文字 最后,我希望得到
<NO>
<L>Some text here </L>
<L>Some additional text here </L>
<L>Still more text here </L>
</NO>
这里有一些文字
这里有一些附加文本
这里还有更多的文字
最后,我希望得到一个字符串属性,它看起来像“这里有一些文本,这里有一些附加文本,这里还有更多文本”
我第一次通过的是接下来的内容。我想我走的是对的,但还不完全正确:
XElement source = \\Output from the Webservice
List<IndexEntry> result;
result = (from indexentry in source.Elements(entryLevel)
select new IndexEntry()
{
EtiologyCode = indexentry.Element("IE") == null ? null : indexentry.Element("IE").Value,
//some code to set other properties in this object
Note = (from l in indexentry.Elements("NO").Descendants
select l.value) //This is where I stop
// and don't know where to go
}
XElement source=\\Webservice的输出
列出结果;
结果=(来自source.Elements(entryLevel)中的indexentry)
选择新IndexEntry()
{
EtiologyCode=indexentry.Element(“IE”)==null?null:indexentry.Element(“IE”).Value,
//一些代码用于设置此对象中的其他属性
注=(从indexentry.Elements(“NO”)子体中的l开始)
选择l.value)//这是我停止的地方
//不知道该去哪里
}
我知道我可以在该查询的末尾添加一个ToList()运算符来返回集合。是否有一种运算符或技术允许我将集合的concatation内联到单个字符串中
如果不清楚,请随时询问更多信息
谢谢。我自己没有使用它的经验,但我觉得它可以大大简化您的代码。选择XML文档,然后循环使用它,并使用StringBuilder将L元素附加到某个字符串。我自己没有使用它的经验,但我觉得它可以大大简化您的代码。选择XML文档,然后循环遍历它,并使用StringBuilder将L元素附加到某个字符串。LINQ to XML确实是这里的方法:
var textArray = topElement.Elements("L")
.Select(x => x.Value)
.ToArray();
var text = string.Join(" ", textArray);
编辑:根据评论,您似乎只需要一种表达方式。这很简单,尽管有点难看:
result = (from indexentry in source.Elements(entryLevel)
select new IndexEntry
{
EtiologyCode = indexentry.Element("IE") == null
? null
: indexentry.Element("IE").Value,
//some code to set other properties in this object
Note = string.Join(" ", indexentry.Elements("NO")
.Descendants()
.Select(x => x.Value)
.ToArray())
};
另一种选择是将其提取到单独的扩展方法中(它必须位于顶级静态类中):
编辑:关于效率的说明
其他答案建议以效率的名义使用StringBuilder
。在使用它之前,我会检查是否有证据表明这是正确的方法。如果你仔细想想,StringBuilder
和ToArray
也会做类似的事情-它们会创建一个比需要大的缓冲区,向其中添加数据,必要时调整大小最后给出一个结果。希望你不需要经常调整大小
StringBuilder
和ToArray
之间的区别在于缓冲的内容-在StringBuilder
中,它是您迄今为止构建的字符串的全部内容。使用ToArray
它只是引用。换句话说,调整ToArray
使用的内部缓冲区的大小可能更便宜而不是调整StringBuilder
的大小,特别是当单个字符串较长时
在ToArray
中进行缓冲后,string.Join
非常有效:它可以查看所有要开始的字符串,精确计算要分配的空间,然后连接它,而不必复制实际的字符数据
这是在-但不幸的是,我不认为我写了基准
我当然不希望ToArray的速度会慢得多,而且我认为这使代码在这里变得更简单-无需使用副作用等,聚合等。LINQ to XML确实是这里的方式:
var textArray = topElement.Elements("L")
.Select(x => x.Value)
.ToArray();
var text = string.Join(" ", textArray);
编辑:根据评论,您似乎只需要一种表达方式。这很简单,尽管有点难看:
result = (from indexentry in source.Elements(entryLevel)
select new IndexEntry
{
EtiologyCode = indexentry.Element("IE") == null
? null
: indexentry.Element("IE").Value,
//some code to set other properties in this object
Note = string.Join(" ", indexentry.Elements("NO")
.Descendants()
.Select(x => x.Value)
.ToArray())
};
另一种选择是将其提取到单独的扩展方法中(它必须位于顶级静态类中):
编辑:关于效率的说明
其他答案建议以效率的名义使用StringBuilder
。在使用它之前,我会检查是否有证据表明这是正确的方法。如果你仔细想想,StringBuilder
和ToArray
也会做类似的事情-它们会创建一个比需要大的缓冲区,向其中添加数据,必要时调整大小最后给出一个结果。希望你不需要经常调整大小
StringBuilder
和ToArray
之间的区别在于缓冲的内容-在StringBuilder
中,它是您迄今为止构建的字符串的全部内容。使用ToArray
它只是引用。换句话说,调整ToArray
使用的内部缓冲区的大小可能更便宜而不是调整StringBuilder
的大小,特别是当单个字符串较长时
在ToArray
中进行缓冲后,string.Join
非常有效:它可以查看所有要开始的字符串,精确计算要分配的空间,然后连接它,而不必复制实际的字符数据
这是在-但不幸的是,我不认为我写了基准
我当然不希望ToArray的速度明显变慢,我认为这会使代码更简单-无需使用副作用等,聚合等。另一种选择是使用聚合()
编辑:聚合中的第一个lambda是累加器。这将获取所有值并从中创建一个值。在这种情况下,它将使用所需文本创建StringBuilder。第二个lambda是结果选择器。这允许您将累积值转换为所需的结果。在本cas中e、 将StringBuilder更改为字符串。另一个选项是使用聚合() 编辑:第一个lambda
var q = topelement.Elements("L")
.Select(x => x.Value)
.Aggregate(new StringBuilder(),
(sb, x) => return sb.Append(x).Append(" "),
sb => sb.ToString().Trim());
using System.Xml;
class Program
{
static void Main(string[] args)
{
XmlDocument d = new XmlDocument();
string xml =
@"<NO>
<L>Some text here </L>
<L>Some additional text here </L>
<L>Still more text here </L>
</NO>";
d.LoadXml(xml);
Console.WriteLine(d.DocumentElement.InnerText);
Console.ReadLine();
}
}