【发布时间】:2014-03-16 08:10:34
【问题描述】:
我正在编写一个将文本转换为 XML 的快速工具。
我创建了一个包含音符编号和新名称的字典。
我想在 XML 中搜索“INote”值(在示例中为“118”)并在 Dictionary 中找到相应的键并替换“Name”值(在示例中为“Sound 119” )
XML 结构如下所示
<list name="Quantize" type="list">
<item>
<int name="Grid" value="4"/>
<int name="Type" value="0"/>
<float name="Swing" value="0"/>
<int name="Unquantized" value="0"/>
<int name="Legato" value="50"/>
</item>
</list>
<list name="Map" type="list">
<item>
<int name="INote" value="118"/>
<int name="ONote" value="118"/>
<int name="Channel" value="9"/>
<float name="Length" value="200"/>
<int name="Mute" value="0"/>
<int name="DisplayNote" value="118"/>
<int name="HeadSymbol" value="0"/>
<int name="Voice" value="0"/>
<int name="PortIndex" value="0"/>
<string name="Name" value="Sound 119" wide="true"/>
<int name="QuantizeIndex" value="0"/>
</item>
<item>
....
</item>
</list>
<list name="Order" type="int">
<item value="0"/>
<item value="1"/>
<item value="2"/>
</list>
到目前为止,这是我的代码:
XDocument outFile = XDocument.Load(outputFile);
var currItem = from item in outFile.Descendants("item")
select item;
foreach (var i in currItem) // this loop is executed many times
{
var node = i.Element("int");
if (node ==null) continue;
var name = node.Attribute("name").Value;
var value = i.Element("int").Attribute("value").Value;
if (name == "INote")
{
var str = i.Element("string").Attribute("name").Value;
if (str == "Name")
{
var snd = i.Element("string").Attribute("value").Value;
MessageBox.Show(string.Format("{0} - {1} - {2} - {3}", name, value,str,snd));
}
}
}
我有两个问题:
查询:有没有办法直接在查询本身而不是在 foreach 循环中执行检查? (作为附加信息,并非所有元素都包含具有“INote”属性的元素)
foreach 循环:整个循环重复了 n 次以上,因此我多次获得从 0 到 n 的 Messagebox。
任何帮助将不胜感激。
答案: 谢谢大家,经过一些测试,我想我已经解决了这个问题:
XDocument outFile = XDocument.Load(outputFile);
var NamesData = outFile.Root.Elements("list")
.Where(x => x.Attribute("name").Value == "Map")
.Elements("item")
.Select(y =>
new KeyValuePair<XAttribute,XAttribute>
(
y.Elements("int").Where(c => c.Attribute("name").Value == "INote").Select(c => c.Attribute("value")).FirstOrDefault(),
y.Elements("string").Where(c => c.Attribute("name").Value == "Name").Select(c => c.Attribute("value")).FirstOrDefault()
)
);
我创建了一个 XAttributes 的 KeyValuePair,这样我就可以轻松地将它们保存回来:
顺便说一句,这是方法的其余部分(注意定义它只是一个数据容器)
foreach (var data in NamesData)
{
NoteDefinition newName;
if (internalDictionary.TryGetValue(Convert.ToInt32(data.Key.Value), out newName))
{
data.Value.SetValue(newName.voiceName);
}
}
outFile.Save(outputFile);
【问题讨论】: