【问题标题】:converting xml of sharepoint list to dataset将共享点列表的 xml 转换为数据集
【发布时间】:2016-03-04 10:36:59
【问题描述】:

已经一个多星期了,我仍然无法弄清楚这里有什么问题。希望你能帮助我。我正在使用 SOAP Web 服务从共享点服务器成功检索 xml,然后我将 xml 转换为数据集对象,我成功获取了数据集,但它“已损坏”——xml 中缺少值的列很少。 这里是使用 SOAP 导入 xml 的代码:

        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;
        } 

我已成功获取数据集,但就像我提到它因缺少值而损坏一样,它们存在于 xml 中但不存在于数据集中(列存在但值不存在)。

请看一下这个屏幕截图:

iv`e 被红色包围的列之一没有从 XML 中获取其值。 这里是 xml 的屏幕截图以及应该在数据集中用红色包围的缺失值:

也尝试将xml转换为这样的数据集,但结果是一样的:

public static DataSet read(XmlNode x) { 

        DataSet ds = new DataSet();

        XmlReader r = new XmlNodeReader(x);

            ds.ReadXml(r);
            return ds;

        }

希望有人可以在这里帮助我。 tnx。

更新:

好的,我还没有解决它,但我发现了一些可能导致解决方案的事情:

  1. 我注意到数据集中所有没有值的列都是用户在网站控件中填写的列,你猜怎么着?这些列的所有标题都是希伯来语,因此在数据集上显示值的列是共享默认列,它们的标题是英文的,并且它们没有 HTML 实体(十六进制)!名称(查看 xml)。所以这让我怀疑这个问题与与希伯来语标题相关的 HTML 实体(十六进制)列名有关......我的假设是数据集无法解释这个 HTML 实体(十六进制)编码。另一个线索是,在数据集中拼写的列名(例如,查看上面 datagridview 的屏幕截图 - 左侧的第 4 列(索引 3))没有正确解释,列名应该是 'שם מתל ' 仅此而已 - 正如您所看到的(您不必为此理解希伯来语)这个希伯来语字符串只有一半存在并连接到编码的 HTML 实体(十六进制)的一部分。

  2. 我注意到,当我在共享点网站中对列进行排序时,请求的 url 使用列的十六进制 html 实体而不是列的希伯来语名称:

http://xxx/xxx/xxx/xxx/Lists/1/view9.aspx?View={c2538b95-efae-453b-b536-aad6f98265ed}&SortField=_x05e9__x05dd__x0020__x05de__x05&SortDir=Desc

我希望看到类似的东西:

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

所以我对我的代码进行了更改,以便在编码的 HTML 实体(十六进制)中显式声明列名,我这样做了(原始代码在上面):

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

现在我在数据集中得到的结果已经改变了!变化是我明确声明它们的列移动到数据集的第一列索引,但这些列中仍然没有任何值。

所以,总结所有这些挖掘,以下是我的假设:

*。问题是 xml 和数据集之间的解释器

*。解释器有缺陷,因为他无法正确解释编码的 HTML 实体(十六进制)

*。用 HTML 实体(十六进制)编写的列标题,因为它们的标题是希伯来语

*。解决方案可以是或将列标题制作为普通希伯来语(在 xml 中),或者做一些使 xml 和数据集之间的解释器正常工作的事情(可能使用 XmlParserContext 类?? - 尝试了一点但没有成功或其他可以操作编码 xml 的类文本)。

【问题讨论】:

    标签: c# xml vb.net sharepoint soap


    【解决方案1】:

    最后,在我完成解决这个问题之后。我找到的解决方案非常简单。

    我一直在寻找解决方案并苦苦挣扎,但从未找到,然后我想到了这个简单的解决方案。

    只需要一行代码:

      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

    从 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;
        }
    

    【讨论】:

      【解决方案2】:

      遇到了同样的问题(通过/到 DataSet 加载 Xml 后缺少值)。 似乎某些字符有问题(在我的情况下为“-”)。

      来自 jonathana 的解决方案(在将数据加载到数据集之前替换属性名称中的字符)。

      我还将为 .NET2 提供一个解决方案,该解决方案更改生成的 SharePoint SOAP 查询 XML 中的所有属性名称,以确保与数据集的对话不会导致错误(可以使用 .NET3+ 更好地完成,但我是强制的在我的情况下到 .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];
      

      【讨论】:

        猜你喜欢
        • 2013-12-06
        • 1970-01-01
        • 2012-01-13
        • 1970-01-01
        • 1970-01-01
        • 2014-04-29
        • 2015-02-01
        • 2017-01-22
        相关资源
        最近更新 更多