作爲替代,這裏是不需要是XML裝飾一些的XDocument和使用對象。
我提倡這種方法,因爲在Xml結構改變的情況下,更容易調整XDocument/Xpath語句.....與XmlAttributes相反。
這也允許使用相同的對象,即使有不同的xml流水化它。您只需爲每個Xml輸入寫一個不同的XDocument「碎紙機」。
[DebuggerDisplay("MyNotUsedStringKey = {MyNotUsedStringKey}")]
public class ImportParent
{
public ImportParent()
{
this.MyNotUsedStringKey = Guid.NewGuid().ToString("N");
this.ImportChildren = new ImportChildCollection();
}
public ImportChildCollection ImportChildren { get; set; }
public string MyNotUsedStringKey { get; set; }
}
public class ImportChildCollection : List<ImportChild>
{
public ImportChildCollection() { }
public ImportChildCollection(IEnumerable<ImportChild> src)
{
if (null != src)
{
foreach (ImportChild item in src)
{
item.Ordinal = this.Count + 1;
base.Add(item);
}
}
//AddRange(src);
}
}
[DebuggerDisplay("MyStringKey = {MyStringKey}, MyStringValue='{MyStringValue}', Ordinal='{Ordinal}'")]
public class ImportChild
{
public ImportChild()
{
}
public int Ordinal { get; set; }
public string MyStringKey { get; set; }
public string MyStringValue { get; set; }
}
string xmlString = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<xml>
<result>OK</result>
<headers>
<header>lastname</header>
<header>firstname</header>
<header>Age</header>
</headers>
<data>
<datum>
<item>Kelly</item>
<item>Grace</item>
<item>33</item>
</datum>
</data>
</xml> ";
XDocument xDoc = XDocument.Parse(xmlString);
//XNamespace ns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
string ns = string.Empty;
List<ImportParent> parentKeys = new List<ImportParent>
(
from list in xDoc.Descendants(ns + "xml")
from item1 in list.Elements(ns + "headers")
where item1 != null
select new ImportParent
{
//note that the cast is simpler to write than the null check in your code
//http://msdn.microsoft.com/en-us/library/bb387049.aspx
ImportChildren = new ImportChildCollection
(
from detail in item1.Descendants("header")
select new ImportChild
{
MyStringKey = detail == null ? string.Empty : detail.Value
}
)
}
);
List<ImportParent> parentValues = new List<ImportParent>
(
from list in xDoc.Descendants(ns + "xml")
from item1 in list.Elements(ns + "data")
from item2 in item1.Elements(ns + "datum")
where item1 != null && item2 != null
select new ImportParent
{
//note that the cast is simpler to write than the null check in your code
//http://msdn.microsoft.com/en-us/library/bb387049.aspx
ImportChildren = new ImportChildCollection
(
from detail in item1.Descendants("item")
select new ImportChild
{
MyStringValue = detail == null ? string.Empty : detail.Value
}
)
}
);
/*Match up the Keys to the Values using "Ordinal" matches*/
foreach (ImportParent parent in parentKeys)
{
foreach (ImportChild child in parent.ImportChildren)
{
ImportChild foundMatch = parentValues.SelectMany(x => x.ImportChildren).Where(c => c.Ordinal == child.Ordinal).FirstOrDefault();
if (null != foundMatch)
{
child.MyStringValue = foundMatch.MyStringValue;
}
}
}
foreach (ImportParent parent in parentKeys)
{
foreach (ImportChild child in parent.ImportChildren)
{
Console.WriteLine("Key={0}, Value={1}", child.MyStringKey, child.MyStringValue);
}
}
這是實際結構嗎?看起來更像是一個具有一堆屬性的單個對象。我建議讓一個類型化的XmlSerializer來處理這個,而不是自己解析它,但爲了給出一個有效的答案,我需要看到真實的結構。 – Filburt
結構是真實的(有更多的領域),但它是。我想創建一個只有標題名稱的對象列表,但正如你所說,最好的方法是使用XmlSerializer併爲我自己解析。 – Baladier
如果你只對'header'元素感興趣,你可以指定'headers'作爲你的反序列化類型的根,並且不用麻煩自己來處理結構的其餘部分。 dbc的答案應該給你一個出發點。 – Filburt