我正在编写一个加载XML文档并将其转换为CSV的函数。由于我只需要XML文件中的一些值,我想要实现的目标是只选择我感兴趣的节点。
这是我的代码:
XDocument csvDocument = XDocument.Load(tempOutput);
StringBuilder csvBuilder = new StringBuilder(1000);
foreach (XElement node in csvDocument.Descendants("Sample"))
{
foreach (XElement innerNode in node.Elements())
{
csvBuilder.AppendFormat("{0},", innerNode.Value);
}
csvBuilder.Remove(csvBuilder.Length -1, 1);
csvBuilder.AppendLine();
}
csvOut = csvBuilder.ToString();
但是,通过这种方式,我选择了“Sample”节点内的所有子节点。
在XML中,“Sample”树是:
<Sample Type="Object" Class ="Sample">
<ID>1</ID>
<Name>10096</Name>
<Type>2</Type>
<Rep>0</Rep>
<Selected>True</Selected>
<Position>1</Position>
<Pattern>0</Pattern>
</Sample>
代码完美无瑕,但我只需选择“ID”和“已选择”,并将其值写入CSV文件。
有人能指出我正确的方向吗?
感谢。
答案 0 :(得分:2)
详细了解Linq-to-xml here。你不是真的利用XObject
s的'linq-edness'
var samples = csvDocument.Descendants("Sample")
.Select(el => new {
Id = el.Element("ID").Value,
Selected = el.Elemnt("Selected").Value
});
这会为您创建一个IEnumerable<T>
,其中'T'
是一个anonymous type,其属性为Id
和Selected
。
您可以解析(int.Parse
或bool.Parse
)类型安全的Id和Selected值。但是因为你只是写一个StringBuilder
对象,你可能不在乎......只是一个FYI。
然后可以按如下方式编写StringBuilder对象:
foreach (var sample in samples) {
csvBuilder.AppendFormat(myFormattedString, sample.Id, sample.Selected);
}
需要注意的是,您的匿名对象和for-each
循环应该在同一范围内。但如果有必要,可以采取各种方法。
与往常一样,给猫皮肤涂抹的方法不止一种。
ref中的更新 ...发表评论:
foreach (XElement node in csvDocument.Descendants("Sample"))
{
foreach (XElement innerNode in node.Elements())
{
// this logic assumes different formatting for values
// otherwise, change if statement to || each comparison
if(innerNode.Name == "ID") {
// append/format stringBuilder
continue;
}
if(innerNode.Name == "Selected") {
// append/format stringBuilder
continue;
}
}
csvBuilder.Remove(csvBuilder.Length -1, 1);
csvBuilder.AppendLine();
}