如何准备深层嵌套节点

时间:2012-08-28 19:27:49

标签: c# xml xpath .net-2.0

我有这种xml doc:

<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 字段:DateTime _date 字段:string _posterName 等等

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

您必须将根元素添加到文档中,然后使用此格式重新测试代码

    <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 :(得分:0)

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

答案 3 :(得分:0)

您提供的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;
        }

    }
}