具有变量属性的XML元素

时间:2011-02-24 16:50:23

标签: c# .net xml sharepoint

我使用SP Web服务从GetListItems中提取数据。我希望尽可能多的数据,因为我将其存储到本地XML文档中。我也尝试从数据中创建TSV。 / p>

返回的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个等)。

如果我明确要求按名称提供属性,那不是什么大问题:

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

获取可能的属性,但我意识到它只会拾取第一行,这可能有也可能没有最大属性。我想过解析整个事情。虽然不太可能,但我也没有真正的方法知道“最大计数”行是否包含每个组合。

对于“null”(缺失)属性是否有更优雅的解决方案并确定所有属性以创建可接受的“列列表”?

4 个答案:

答案 0 :(得分: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);
      }
    }
  }
}

答案 1 :(得分:0)

您最好的选择是了解从中获取项目的列表的架构。这样,您还可以找到字段的内部名称(xml格式:ows_部分)。

答案 2 :(得分:0)

创建一个Serializable类来保存所有文档。 (正如 JamesLove 所说,您需要知道您尝试解析的架构XML文档。)

您可以使用[XmlElement]等属性标记类的数据保持属性(请参阅MSDN上的更多内容),以控制类的对象(de)序列化的方式。目标(在许多情况下可实现)是标记它,以便只需一次调用XmlSerializer即可完成(反)序列化。

作为一般规则,请尽量减少代码中自定义,过程式XML解析例程的数量。 XML序列化不是一个特性,它是最终用户和客户完全不关心的东西。

答案 3 :(得分:0)

我认为你的问题的核心是你想要知道#RowsetSchema命名空间中row命名空间中那些元素上出现的所有属性(不包括命名空间声明)的唯一名称。 1}}。

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