2011-02-24 148 views
1

我使用SP Web服務從GetListItems中下拉數據我希望得到儘可能多的數據,因爲我將該數據存儲到本地XML文檔中我還試圖創建TSV從具有可變屬性的XML元素

數據返回的XML是這樣的:

<rs:data ItemCount="896" xmlns:rs="urn:schemas-microsoft-com:rowset"> 
<z:row ows_A="1" ows_B="2" xmlns:z="#RowsetSchema" /> 

有實際上更接近60 +每行的屬性,這個問題是每個「行」返回的屬性不一致(如有的有60,有的有67,有的有59等)

如果我icitly要求按名稱的屬性,它不是一個大問題:

foreach (System.Xml.XmlNode listItem in nodeListItems) 
      { 
if (listItem.Name == "rs:data") 
       { 
        for (int i = 0; i < listItem.ChildNodes.Count; i++) 
        { 
         if (listItem.ChildNodes[i].Name == "z:row") 
         { 
          wtSr.Append(listItem.ChildNodes[i].Attributes["ows_Title"].Value); 
          wtSr.Append("\t"); 

等,等

我試圖使用像

for (int k = 0; k < listItem.ChildNodes[i].Attributes.Count; k++) 
{ 
            tmpWtCol =           listItem.ChildNodes[i].Attributes[k].Name.ToString().Replace("ows_", string.Empty).Replace("_", string.Empty); 
            wtSr.Append(tmpWtCol + "\t"); 


            wtDidHeaders = true; 
           } 

收穫的人可能經過的所有屬性解析屬性,但我意識到它只會選取第一行,可能有或沒有最大屬性。我想過分析整個事情。雖然這不太可能,但我也沒有真正的方法知道「最大計數」行是否包含所有組合。

是否有一個更優雅的解決方案與「空白」(缺少)屬性和確定所有屬性創建一個可接受的「列列表」?

回答

0

我認爲你的問題的核心是你想知道#RowsetSchema命名空間中名爲row的文檔中那些元素上出現的所有屬性(不包括名稱空間聲明)的唯一名稱。

LINQ是你的朋友:

foreach (string s in doc.Descendants() 
    .Where(x => x.Name.NamespaceName == "#RowsetSchema") 
    .Attributes() 
    .Where(x => !x.IsNamespaceDeclaration) 
    .Select(x => x.Name.LocalName) 
    .Distinct()) 
{ 
    Console.WriteLine(s); 
} 
0

你最好的選擇是知道你從中獲取物品的列表模式。這樣,您將能夠找出字段的內部名稱(xml格式:ows_部分)。

+0

+1用於向原始的海報的程序的輸入的XML模式轉向了談話。 – azheglov 2011-02-24 18:06:28

+0

您在這裏可能做出三個假設:1 - 提交者不瞭解XML模式的目的或存在。2 - 如果他們知道,他們還沒有遇到阻止/阻止他們將代碼綁定到模式版本的情況。 3 - 基於模式序列化XML會很有效。如果提交者使用100Mb的XML,他想要做的最後一件事是序列化它。 – 2011-02-24 19:07:20

+0

我沒有提到XML模式,我的意思是列表模式。提交者的價值數據很可能是存儲在SharePoint列表中的用戶生成的數據。瞭解這些列的內部名稱將有助於提交者知道從XML中提取哪些數據。 – 2011-02-24 19:35:37

1

如果你必須使用一個XmlReader的靈活性,你可以這樣做:

HashSet<string> attributeNames = new HashSet<string>(); 

xmlReader = listItem.CreateNavigator().ReadSubtree(); 

while (xmlReader.Read()) 
{ 
    if (xmlReader.NodeType == XmlNodeType.Element 
    && xmlReader.Name == "rs:data") 
    { 
    if (xmlReader.HasAttributes) 
    { 
     int attributeCount = xmlReader.AttributeCount; 
     for (int i = 0; i < attributeCount; i++) 
     { 
     xmlReader.MoveToAttribute(i); 
     attributeNames.Add(xmlReader.Name); 
     } 
    } 
    } 
} 
0

創建一個Serializable類來保存所有文件。 (由於JamesLove說,你需要知道你試圖解析模式的XML文檔。)

您可以像使用[XmlElement]屬性標記類的數據保持特性(多看它們在MSDN )來控制你的類的對象是如何被序列化的。目標(在很多情況下是可以實現的)是標記它,這樣只需要對XmlSerializer進行一次調用即可完成(反)序列化。

作爲一般規則,儘量減少代碼中自定義過程式XML解析例程的數量。 XML序列化不是功能,它是最終用戶和客戶完全不關心的事情。