2016-03-04 64 views
0

已經超過一週了,我仍然無法弄清楚這裏有什麼問題。希望你能幫助我。我成功地從共享點服務器使用SOAP Web服務檢索XML,然後我將XML轉換爲數據集對象,我成功獲取數據集,但它的「損壞」 - 有少數列從XML中缺少值。 這裏是使用SOAP導入XML代碼:將XML的Sharepoint列表轉換爲數據集

 private void button2_Click(object sender, EventArgs e) 
     { 
      oportal.Lists list = new oportal.Lists(); 
      list.Credentials = System.Net.CredentialCache.DefaultCredentials; 
      list.Url = "http://xxx/xxx/xxx/xxx/_vti_bin/Lists.asmx"; 

      XmlDocument xmlDoc = new System.Xml.XmlDocument(); 

      XmlNode ndQUery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", ""); 
      XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", ""); 
      XmlNode ndQueryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", ""); 

      ndQueryOptions.InnerXml = 
      "<IncludeMandatoryColumns>TRUE</IncludeMandatoryColumns>" + 
      "<DateInUtc>FALSE</DateInUtc>"; 

      ndViewFields.InnerXml = @"<FieldRef Name='שם לקוח' /> 
    <FieldRef Name='שם מתל'/>"; 




      try 
      { 
       XmlNode ndListItems = list.GetListItems("{DD1CF626-62E1-4E36-BF2B-C7D08EA73674}",null, ndQUery, ndViewFields, "14000", ndQueryOptions, null); 
       System.Diagnostics.Debug.WriteLine(ndListItems.OuterXml); 

       dataGridView1.DataSource = ConverttYourXmlNodeToDataSet(ndListItems).Tables[1]; 
      } 
      catch(System.Web.Services.Protocols.SoapException ex) { 
       MessageBox.Show(ex.Message + Environment.NewLine + ex.Detail.InnerText + Environment.NewLine + ex.StackTrace); 

      } 

     } 

我得到的XML看起來不錯,列(字段)的名字在希伯來語但XML顯示他們在HTML實體(十六進制) - 也許這就是問題的根源?

我得到的XML我正在將其轉換成數據集ConverttYourXmlNodeToDataSet()函數在此之後是代碼:

public static DataSet ConverttYourXmlNodeToDataSet(XmlNode xmlnodeinput) 
     { 
      DataSet dataset = null; 
      if (xmlnodeinput != null) 
      { 
       XmlTextReader xtr = new XmlTextReader(xmlnodeinput.OuterXml, XmlNodeType.Element,null); 
       dataset = new DataSet(); 
       dataset.ReadXml(xtr); 
      } 

      return dataset; 
     } 

我得到succefuly數據集,但就像我提到的,因爲缺失值的損壞,它們存在於xml中,但不存在於數據集中(列存在但不包含值)。

請看看這個畫面拍:

Dataset of sharepoint list xml

iv`e紅色的顏色,不從XML其價值的一列包圍。 這裏是XML的屏幕拍攝和缺失值,應該是與紅色surronded數據集:

XML of sharepoint list

也tryed到XML轉換爲數據集一​​樣,但結果都是一樣的:

public static DataSet read(XmlNode x) { 

     DataSet ds = new DataSet(); 

     XmlReader r = new XmlNodeReader(x); 

      ds.ReadXml(r); 
      return ds; 

     } 

希望有人能幫助我這裏。 TNX。

UPDATE:

確定我還沒有解決它,但是我發現幾件事情,可能會導致解決方案:

  1. 我已經注意到,如果沒有值出現在列數據集是用戶在網站控件中填充的列,並猜測是什麼?這些列的所有標題都是希伯來語,因此在數據集中顯示值的列是sharepint默認列,其標題是英文,並且沒有HTML實體(十六進制)!名稱(看看xml)。因此,這讓我懷疑問題與與希伯來字幕相關的HTML實體(十六進制)列名有關......我的假設是數據集無法解釋此HTML實體(十六進制)編碼。另一個線索是列名稱與數據集中拼寫的相同(例如,查看上面的datagridview的屏幕截圖 - 左側(索引3)的第4列)沒有被正確解釋,列名應該是'שםמתל '這就是所有 - 正如你所看到的(你不必爲此理解希伯來語),這個希伯來語字符串中只有一半在那裏,並連接到編碼的HTML實體(十六進制)的一部分。

  2. 我已經注意到,當IM排序在共享點的網站列使用列的十六進制HTML實體,而不是列的希伯來名字所請求的URL:

http://xxx/xxx/xxx/xxx/Lists/1/view9.aspx?View= {c2538b95,efae- 453B-b536-aad6f98265ed} & =的SortField _x05e9__x05dd__x0020__x05de__x05 & SortDir =說明

和我期望看到類似:

http://xxx/xxx/xxx/xxx/Lists/1/view9.aspx?View= {c2538b95-efae-453B-b536-aad6f98265ed} &的SortField = _ 'שםמתל'=說明

所以我提出在我的代碼的變化,以顯式地聲明在經編碼的HTML實體中的列名(十六進制)並且我這樣做了(原始代碼在上面):

ndViewFields.InnerXml = @"<FieldRef Name='_x05d0__x05d9__x05e9__x05d5__x05' /> 
    <FieldRef Name='_x05e9__x05dd__x0020__x05de__x05'/>"; 

現在我在數據集中得到的結果已經改變!改變是我明確聲明它們移動到數據集的第一列索引但是在這些列中沒有任何值的列。

所以,夏日的所有挖的,這裏是我的假設:

*。問題是xml和數據集之間的解釋器

*。口譯員是有缺陷的,因爲他無法正確理解生硬的HTML實體(十六進制)

*。以HTML實體(十六進制)寫成的列標題,因爲它們的標題在希伯來語

*。解決方案可以是將列標題設置爲簡單的希伯來語(在xml中),或者做一些可以使xml和數據集之間的解釋器正常工作的東西(也許使用XmlParserContext類 - 嘗試一點沒有成功或其他可以操縱編碼xml的類文本)。

回答

0

最後,我已經完成解決這個問題。我發現的解決方案非常簡單。

我一直在尋找解決方案併爲之奮鬥一段時間,從未找到解決方案,然後這個簡單的解決方案跨過了我的腦海。需要

只有一行代碼:

String s = xmlnodeinput.OuterXml.Replace("ows__x05e9__x05dd__x0020__x05de__x05", 
"AccountManager"); 

剛剛更換的十六進制值和數據集正確加載。

還我檢查,看看有沒有時間等待處理的問題(替換字符串只需花費不到一秒鐘):

開始讀取12000行:26/03/2016 17點18分00秒開始 替換字符串: 26/03/2016 17時18分04秒 裝載XML字符串數據集:26/03/2016 17時18分04秒 完成加載數據集:26/03/2016 17時18分04秒

從complte converstion xml到數據集函數:

public static DataSet ConverttYourXmlNodeToDataSet(XmlNode xmlnodeinput) 
    { 
     //declaring data set object 
     DataSet dataset = null; 
     if (xmlnodeinput != null) 
     { 
      NameTable nt = new NameTable(); 
      nt.Add("row"); 
      XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt); 
      XmlParserContext context = new XmlParserContext(nt, null, "heb",null, null, null, null, null, XmlSpace.None,Encoding.Unicode); 

      String s = xmlnodeinput.OuterXml.Replace("ows__x05e9__x05dd__x0020__x05de__x05", "AccountManager"); 

      XmlTextReader xtr = new XmlTextReader(s, XmlNodeType.Element,context); 

      dataset = new DataSet(); 

      dataset.ReadXml(xtr); 
     } 

     return dataset; 
    } 
0

遇到同樣的問題(Xml通過/加載到DataSet後缺少值)。 似乎有一些字符有問題(在我的情況下「 - 」)。

jonathana的解決方案工作(在將數據加載到數據集之前,從屬性名稱中替換字符)。

我還將爲.NET2提供一個解決方案,它改變生成的SharePoint SOAP查詢XML中的所有屬性名稱,以確保與數據集的對話不會導致錯誤(可以使用.NET3 +更好地完成,但是im在我的情況下強制爲.NET2):

using System.Text.RegularExpressions; 
using System.Web; 
using System.Xml; 

XmlDocument doc = new XmlDocument(); 

doc.LoadXml(spResXml.OuterXml); 
System.Xml.XmlNamespaceManager nm = new System.Xml.XmlNamespaceManager(doc.NameTable); 
nm.AddNamespace("rs", "urn:schemas-microsoft-com:rowset"); 
nm.AddNamespace("z", "#RowsetSchema"); 
nm.AddNamespace("rootNS", "http://schemas.microsoft.com/sharepoint/soap"); 

var zRows = doc.SelectNodes("//z:row", nm); 
for (int i = 0; i < zRows.Count; i++) 
{ 
    XmlNode zRow = zRows[i]; 
    List<XmlAttribute> attsList = new List<XmlAttribute>(); 
    for (int j = 0; j < zRow.Attributes.Count; j++) 
    { attsList.Add(zRow.Attributes[j]); } 

    foreach (XmlAttribute att in attsList) 
    { 
     string patchedAttName = att.Name; 
     patchedAttName = patchedAttName.Replace("_x", "%u"); 
     patchedAttName = HttpUtility.UrlDecode(patchedAttName); 
     patchedAttName = Regex.Replace(patchedAttName,"[^A-Za-z0-9_]", "_", RegexOptions.None); 
     if (att.Name.Equals(patchedAttName)) 
     { continue; } 
     var newAtt = doc.CreateAttribute(att.Prefix, patchedAttName, att.NamespaceURI); 
     newAtt.Value = att.Value; 
     zRow.Attributes.Remove(att); 
     zRow.Attributes.Append(newAtt); 
    } 
} 
DataSet ds = new DataSet(); 
ds.ReadXml(new XmlNodeReader(doc)); 
DataTable t = ds.Tables[1];