2014-11-04 34 views
1

我想從Microsoft Dynamics環境中將一些SQL數據提取到XML,我目前在C#中使用LINQ to XML來讀取和寫入我的XML文件。我需要的一個數據是來自SECURITYSUBROLE的視圖。查看此視圖​​的結構顯示,還有一個名爲SECURITYSUBROLE的列。我的常規提取方法給了我這個XML。當XML父和子節點具有相同名稱時如何使用LINQ to XML

<SECURITYSUBROLE> 
    <SECURITYROLE>886301</SECURITYROLE> 
    <SECURITYSUBROLE>886317</SECURITYSUBROLE> 
    <VALIDFROM>1900-01-01T00:00:00-06:00</VALIDFROM> 
    <VALIDFROMTZID>0</VALIDFROMTZID> 
    <VALIDTO>1900-01-01T00:00:00-06:00</VALIDTO> 
    <VALIDTOTZID>0</VALIDTOTZID> 
    <RECVERSION>1</RECVERSION> 
    <RECID>886317</RECID> 
</SECURITYSUBROLE> 

當我嘗試稍後導入此數據,我得到錯誤,因爲父XML節點具有相同的名稱作爲子節點。下面是導入方法的一個片段:

XmlReaderSettings settings = new XmlReaderSettings(); 
settings.CheckCharacters = false; 

XmlReader reader = XmlReader.Create(path, settings); 

reader.MoveToContent(); 
int count = 1; 
List<XElement> xmlSubset = new List<XElement>(); 
while (reader.ReadToFollowing(xmlTag)) 
{ 
    if (count % 1000 == 0) 
    { 
    xmlSubset.Add(XElement.Load(reader.ReadSubtree())); 
    XDocument xmlTemp = new XDocument(new XElement(xmlTag)); 
    foreach (XElement elem in xmlSubset) 
    { 
    xmlTemp.Root.Add(elem); 
    } 
    xmlSubset = new List<XElement>(); 
    ImportTableByName(connectionString, tableName, xmlTemp); 
    count = 1; 
    } 
    else 
    { 
    xmlSubset.Add(XElement.Load(reader.ReadSubtree())); 
    count++; 
    } 
    } 
} 

它目前沒有在XmlReader.ReadToFollowing,它不知道下次去因爲這個名字混淆。所以我的問題有兩個部分:

1)有沒有更好的方法來提取此數據,而不是XML?

2)有沒有通過LINQ To XML的方式,我可以以某種方式區分名爲完全相同的父節點和子節點?

+0

讓我猜猜,你使用'Descendants'方法?使用'Elements'來代替,你應該沒問題。 – MarcinJuraszek 2014-11-04 04:31:54

回答

1

要獲得SECURITYSUBROLE您可以檢查是否元素的有孩子的元素(你的情況):

XElement root = XElement.Load(path); 
var subroles = root.Descendants("SECURITYSUBROLE") // all subroles 
        .Where(x => !x.HasElements); // only subroles without children 
+0

如果我正在處理普通大小的XML文件,這將是一個完美的解決方案,我使用XmlReader的原因是因爲生成的XML文件有時達到2GB或更大,並且如果嘗試將整個東西加載到XElement對象中。有沒有辦法在使用XmlReader時仍然利用您的解決方案? – 2014-11-06 01:01:05

+0

@crypticApps你的問題標題是Linq-to-xml,它不是XmlReader。你爲什麼不讓自己的項目成爲64位並放入各種編譯標誌,以便使用大量內存。如果您想知道如何做到這一點,請將其作爲單獨的問題提出。 – 2014-11-06 05:36:56

+0

我接受這個答案,因爲它對我所問的問題是正確的,謝謝查克! – 2014-11-06 16:49:43

0

我要提出一個不同的方法:

1)VS2013(可能更早的版本太)具有以下功能:從XML源創建一個類。因此,獲取您的一個XML文件並將內容複製到剪貼板。然後,在一個新的類文件Edit - >Paste Special - >Paste XML as Classes

2)。看看XmlSerialization,這將讓你的XML文件轉換爲內存中的對象有一個強類型的類。

 XmlSerializer s = new XmlSerializer(yourNewClassTYPE); 
     TextReader r = new StreamReader(XmlFileLocation); 
     var dataFromYourXmlAsAStronglyTypedClass = (yourNewlyClassTYPE) s.Deserialize(r); 
     r.Close(); 
相關問題