【问题标题】:How to ready deeply nested nodes如何准备深度嵌套的节点
【发布时间】:2012-08-28 19:27:48
【问题描述】:

我得到了这种 xml 文档:

<root>
    <class_table>
      <class_title>
        <class_name>SomeClassBla</class_name>
      </class_title>
      <fields>
        <field_name>DateTime _date</field_name>
        <field_name>string _posterName</field_name>
        <field_name>string _commentText</field_name>
        <field_name>bool _visible</field_name>
      </fields>
      <properties>
        <property_name>DateTime Date</property_name>
        <property_name>string PosterName</property_name>
        <property_name>string CommentText</property_name>
        <property_name>bool Visible</property_name>
      </properties>
      <methods />
      <inheritance />
    </class_table>
    <class_table>
      <class_title>
        <class_name>someAnotnerClass</class_name>
      </class_title>
      <fields>
        <field_name>int result</field_name>
        <field_name>string test</field_name>
      </fields>
      <properties>
        <property_name>string BlogPage</property_name>
        <property_name>string BlogPostPage</property_name>
        <property_name>string ErrorPage</property_name>
        <property_name>string ComingSoonPage</property_name>
      </properties>
      <methods>
        <method_name>string DateFormatter()</method_name>
        <method_name>string EncodeBase64()</method_name>
        <method_name>string DecodeBase64()</method_name>
        <method_name>string CategoriesFormatterTyped()</method_name>
        <method_name>string AddShareThisLink()</method_name>
        <method_name>string ShortenText()</method_name>
        <method_name>string CommentCountFormatter()</method_name>
        <method_name>string MtaShorten()</method_name>
      </methods>
      <inheritance />
    </class_table>
</root>

那么我如何读取这 2 个 class_table 节点的所有字段名称?它的嵌套深层使用此代码:

XmlDocument readDiagramXml = new XmlDocument();
readDiagramXml.Load(classDiagramFile);

XmlNodeList classTables = readDiagramXml.GetElementsByTagName("class_table");
foreach (XmlNode items in classTables)
{
    string className = items["fields/fields_name"].InnerText;
    File.AppendAllText("A_class_diagram_test.txt", className + Environment.NewLine);
}

我得到对象引用错误。我想要的只是将每个节点的值写入具有该格式的 txt 文件: 类名 = SomeClassBla 字段:日期时间_date 字段:字符串_posterName 等等

【问题讨论】:

  • 将自己升级到 XDocument。
  • 缺少根元素,因为它是动态生成的 xml。我已经加了。我可以使用 XDocument 并且不能使用 ling2xml - 它是一个 .NET 2.0 项目。
  • 以后限制在旧版本的时候再提一下。

标签: c# xml xpath .net-2.0


【解决方案1】:

将根元素添加到您的 xml 后,您可以使用 Linq2Xml 轻松解析它

XDocument xDoc = XDocument.Parse(xml); //or .Load(filename)
var classes = xDoc
    .Descendants("class_table")
    .Select(clazz => new
    {
        Name = clazz.Descendants("class_name").First().Value,
        Fields = clazz.Descendants("field_name").Select(x=>x.Value).ToList(),
        Properties = clazz.Descendants("property_name").Select(x=>x.Value).ToList(),
        Methods = clazz.Descendants("method_name").Select(x=>x.Value).ToList(),
    })
    .ToList();

编辑

另一个使用XmlSerializer的例子

//Assuming your(missing) root element is "root"
XmlSerializer ser = new XmlSerializer(typeof(class_table[]),new XmlRootAttribute("root"));
class_table[] obj = (class_table[])ser.Deserialize(stream);


public class class_table
{
    [XmlArrayItem("field_name")]
    public List<string> fields;

    [XmlArrayItem("property_name")]
    public List<string> properties;

    [XmlArrayItem("method_name")]
    public List<string> methods;
}

【讨论】:

  • 我不能使用 ling2xml - 它的 .NET 2.0 项目
【解决方案2】:

你必须在你的文档中添加根元素,用这种格式重新测试你的代码

    <root>

 <class_table>
  <class_title>
    <class_name>SomeClassBla</class_name>
  </class_title>
  <fields>
    <field_name>DateTime _date</field_name>
    <field_name>string _posterName</field_name>
    <field_name>string _commentText</field_name>
    <field_name>bool _visible</field_name>
  </fields>
  <properties>
    <property_name>DateTime Date</property_name>
    <property_name>string PosterName</property_name>
    <property_name>string CommentText</property_name>
    <property_name>bool Visible</property_name>
  </properties>
  <methods />
  <inheritance />
</class_table>
<class_table>
  <class_title>
    <class_name>someAnotnerClass</class_name>
  </class_title>
  <fields>
    <field_name>int result</field_name>
    <field_name>string test</field_name>
  </fields>
  <properties>
    <property_name>string BlogPage</property_name>
    <property_name>string BlogPostPage</property_name>
    <property_name>string ErrorPage</property_name>
    <property_name>string ComingSoonPage</property_name>
  </properties>
  <methods>
    <method_name>string DateFormatter()</method_name>
    <method_name>string EncodeBase64()</method_name>
    <method_name>string DecodeBase64()</method_name>
    <method_name>string CategoriesFormatterTyped()</method_name>
    <method_name>string AddShareThisLink()</method_name>
    <method_name>string ShortenText()</method_name>
    <method_name>string CommentCountFormatter()</method_name>
    <method_name>string MtaShorten()</method_name>
  </methods>
  <inheritance />
</class_table>


    </root>

【讨论】:

    【解决方案3】:

    items["field/field_name"] 返回了多个项目,我没有看到任何与“field/fields_name”相对应的元素尝试从代码中删除“s”items["fields/fields_name"]

    试试这样的:

    (我还没有尝试过,所以可能需要进行一些调试,但我认为这是你的问题)

    XmlNodeList classTables = xml.SelectNodes("//class_table/fields/fields_name");
    //XmlNodeList classTables = readDiagramXml.GetElementsByTagName("class_table");
    foreach (XmlNode items in classTables)
    {
        string className = items.InnerText;
        foreach (
        File.AppendAllText("A_class_diagram_test.txt", className + Environment.NewLine);
    }
    

    【讨论】:

      【解决方案4】:

      您提供的 XML 似乎没有根元素。所以当你试图解析它时它会抛出一个错误。我会添加一个根元素

      <root>
         <class_table>
          //some content
         </class_table>
         <class_table>
          //some content
         </class_table>
      </root>
      

      现在我们可以使用 LINQtoXML 来解析它了。

      var path = Server.MapPath("~/Content/pathToYourFile.xml");           
      XElement elm = XElement.Load(path);
      if (elm != null)
      {
          foreach (var item in elm.Elements("class_table"))
          {
              string className = item.Element("class_title").
                                                    Element("class_name").Value;       
      
              foreach (var field in item.Element("fields").
                                                     Elements("field_name"))
              {
                  string fieldName = field.Value;
              }
              foreach (var prop in item.Element("properties").
                                                          Elements("property_name"))
              {
                  string propName = prop.Value;
              }
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多