<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping   xmlns="urn:nhibernate-mapping-2.2"
    assembly="Model" namespace="Model">
  <class name ="Model.UserInfo,Model" table="BIWEILUN">
    <id name="ID" column="ID" type="Int32" unsaved-value="0">
      <generator class ="increment">      </generator>
    </id>
    <property name="UserID" column ="UserID" type="string" length="20" not-null="false"/>
    <property name="UserName" column ="UserName" type="string" length="20" not-null="false"/>
    <property name="PassWord" column ="PassWord" type="string" length="20" not-null="false"/>
    <property name="SafeCode" column ="SafeCode" type="string" length="20" not-null="false"/>
    <property name="Question1" column ="Question1" type="string" length="20" not-null="false"/>
    <property name="Answer1" column ="Answer1" type="string" length="20" not-null="false"/>
    <property name="Question2" column ="Question2" type="string" length="20" not-null="false"/>
    <property name="Answer2" column ="Answer2" type="string" length="20" not-null="false"/>
    <property name="Mail" column="Mail" type="string" length="20" not-null="false" />
    <property name="TrueName" column ="TrueName" type="string" length="20" not-null="false"/>
    <property name="Sex" column ="Sex" type="string" length="4" not-null="false"/>
    <property name="PersonID" column ="PersonID" type="string" length="30" not-null="false"/>
    <property name="Job" column ="Job" type="string" length="20" not-null="false"/>
    <property name="PlaceFrom" column ="PlaceFrom" type="string" length="10" not-null="false"/>
    <property name="Role" column ="Role" type="string" length="10" not-null="false"/>
    
  </class>
</hibernate-mapping>
XML文件如上,hibernate-mapping是根,下面有1个Child——class,class下面有一个ID的子结点,和很多property的子节点我现在只写出了这样的代码:
            string xmlPath = Server.MapPath("~/User.xml");
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(xmlPath);
            XmlNode root = xDoc.DocumentElement;
            XmlNode classnode = root.ChildNodes[0];
            XmlNodeList propertyList = classnode.ChildNodes;以上四句都能成功得到我想要的结构,但是propertyList得到的是包含ID的class下面的所有子节点,如果我用
XmlNodeList propertyList2 = classnode.SelectNodes("property");
却不能取到所有的property。是不是SelectNodes只对这样的XML格式有效果?
<propert>
<name>UserID</name>
<column>UserID</column>
...
</propert>我现在就是要向所有的property后添加
<property name="xxx" column ="xxx" type="string" length="10" not-null="false"/>
这样的,怎么做?

解决方案 »

  1.   

    XMLElement  XmlAttribute把头都搞大了,还是没弄出来。这个题目对熟悉XML操作的朋友应该很简单,敬请不吝赐教
      

  2.   

    你需要的也许是这个吧,猜的            string xmlPath = Server.MapPath("~/User.xml");
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(xmlPath);
                XmlNode root = xDoc.DocumentElement;
    XmlNode classnode = root.ChildNodes[0]; XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);
    nsmgr.AddNamespace("nh2.2", "urn:nhibernate-mapping-2.2"); XmlNodeList propertyList = classnode.SelectNodes("nh2.2:property", nsmgr);
      

  3.   


    以下例子在user.xml中增加了一个时间属性,如果用Xpath将会更加方便。using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Xml;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                XmlDocument xml = new XmlDocument();
                xml.Load("User.xml");
                XmlNodeList nodelist = xml.GetElementsByTagName("property");            foreach (XmlNode node in nodelist)
                {
                    XmlElement element = (XmlElement)node;
                    //增加时间属性
                    element.SetAttribute("time", DateTime.Now.ToString());
                    Console.WriteLine(element.GetAttribute("time").ToString());
                }            //保存xml
                xml.Save("User.xml");            Console.ReadKey();
            }
        }
    }
      

  4.   

    不是增加属性就像
    <property name="UserID" column ="UserID" type="string" length="20" not-null="false"/>
    <property name="UserName" column ="UserName" type="string" length="20" not-null="false"/>
    <property name="PassWord" column ="PassWord" type="string" length="20" not-null="false"/>我想再加上一行格式差不多的,变成<property name="UserID" column ="UserID" type="string" length="20" not-null="false"/>
    <property name="UserName" column ="UserName" type="string" length="20" not-null="false"/>
    <property name="PassWord" column ="PassWord" type="string" length="20" not-null="false"/>
    <property name="xxx" column ="xxx" type="string" length="20" not-null="false"/>只是对这种格式的XML操作不会

    <propert>
    <name>UserID</name>
    <column>UserID</column>
    ...
    </propert>这种格式的我会,用XMLNodeList就行了
      

  5.   

     XmlNodeList nodes = doc.SelectNodes("/*[local-name()='hibernate-mapping']/*[local-name()='class']/*[local-name()='property']");
     
      

  6.   


    XmlDocument doc = new XmlDocument();
                doc.Load("test.xml");
                XmlNodeList nodes = doc.SelectNodes("/*[local-name()='hibernate-mapping']/*[local-name()='class']/*[local-name()='property']");
                
      

  7.   

    感谢这位大哥,确实取到了。那我问下,为什么这样不行呢?
    string xmlPath = Server.MapPath("~/User.xml"); 
    XmlDocument xDoc = new XmlDocument(); 
    xDoc.Load(xmlPath); 
    XmlNode root = xDoc.DocumentElement; 
    XmlNode classnode = root.ChildNodes[0]; 
    XmlNodeList nodes = classnode.SelectNodes("/*[local-name()='property']");//这样就取不到了
    取到了还有插入的问题,怎么向后面插入
    <property name="xxx" column ="xxx" type="string" length="20" not-null="false"/> 
    这种格式的呢?
      

  8.   

    ("/*[local-name()='hibernate-mapping']/*[local-name()='class']/*[local-name()='property']"); 
    给你解释:
    /第1层名称=hibernate-mapping的所有节点/第2层名称=class的所有节点/第3层名称=property的所有节点注意层次关系. 一个斜杠表示1层。具体可参照 Xpath 语法----------------
    classnode.SelectNodes("/*[local-name()='property']");//这样就取不到了
    你这个意思是 取 第一层名称=property的所有节点 ,因为第一层没有名称为property的节点。 所以你取出来的是空的。----------取到了还有插入的问题,怎么向后面插入 
    <property name="xxx" column ="xxx" type="string" length="20" not-null="false"/> 
    这种格式的呢?
    --------------------------稍后给代码
      

  9.   

    追加节点如下: 随便找个节点克隆 追加到父节点        private void button1_Click(object sender, EventArgs e)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load("test.xml");
                XmlNodeList nodes = doc.SelectNodes("/*[local-name()='hibernate-mapping']/*[local-name()='class']/*[local-name()='property']");
               
                
                if (nodes.Count > 0 &&  nodes[0].ParentNode !=null)
                {
                    XmlNode xnNew = nodes[0].Clone();
                    nodes[0].ParentNode.AppendChild(xnNew);
                    //怎么修改 xnNew 不需要说了吧?
                      
                }
                doc.Save("test_out.xml");
     
            }
      

  10.   

    修改xnNew虽然我不会,但是我想我应该可以自己摸索出来。我可否再问个问题,不用克隆的方法,怎么拼凑出一个
    <property name="xxx" column ="xxx" type="string" length="20" not-null="false"/> 这种格式的XMLNode?或是XmlElement?我感觉这个好像不是XmlNode初学者请大哥不吝赐教,一直在搞C++的,刚转型....
      

  11.   

    你客气了! 不用克隆的方法, XmlElement xe = doc.CreateElement("","property","urn:nhibernate-mapping-2.2");                         private void button1_Click(object sender, EventArgs e)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load("test.xml");
                XmlNodeList nodes = doc.SelectNodes("/*[local-name()='hibernate-mapping']/*[local-name()='class']/*[local-name()='property']");
               
                
                if (nodes.Count > 0 &&  nodes[0].ParentNode !=null)
                {
                    XmlNode xnNew = nodes[0].Clone();
                    nodes[0].ParentNode.AppendChild(xnNew);
                    //怎么修改 xnNew 不需要说了吧? 
                      XmlElement xe = doc.CreateElement("","property","urn:nhibernate-mapping-2.2");                 
                    XmlAttribute xa = doc.CreateAttribute("name");  
                    xa.Value="role3";  
                    xe.Attributes.Append(xa);
                    nodes[0].ParentNode.AppendChild(xe);                  
                }
                doc.Save("test_out.xml");
     
            }
      

  12.   

     XmlNode 是抽象类  XmlElement XmlAttribute  都是继承它.可查看原型 
      

  13.   

    谢谢大哥的讲解最后一个小问题:
    我是这么取到所有property的XmlNodeList的,而且确实取到了XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);
    nsmgr.AddNamespace("root", "urn:nhibernate-mapping-2.2");XmlNodeList propertyList = root.SelectNodes("/root:hibernate-mapping/root:class/root:property", nsmgr);
    我现在要把他们从XML中抹掉该怎么办?就是把<?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping   xmlns="urn:nhibernate-mapping-2.2"
        assembly="Model" namespace="Model">
      <class name ="Model.UserInfo,Model" table="BIWEILUN">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
          <generator class ="increment">      </generator>
        </id>
        <property name="UserID" column ="UserID" type="string" length="20" not-null="false"/>
        <property name="UserName" column ="UserName" type="string" length="20" not-null="false"/>
        <property name="PassWord" column ="PassWord" type="string" length="20" not-null="false"/>
        <property name="SafeCode" column ="SafeCode" type="string" length="20" not-null="false"/>
        <property name="Question1" column ="Question1" type="string" length="20" not-null="false"/>
        <property name="Answer1" column ="Answer1" type="string" length="20" not-null="false"/>
        <property name="Question2" column ="Question2" type="string" length="20" not-null="false"/>
        <property name="Answer2" column ="Answer2" type="string" length="20" not-null="false"/>
        <property name="Mail" column="Mail" type="string" length="20" not-null="false" />
        <property name="TrueName" column ="TrueName" type="string" length="20" not-null="false"/>
        <property name="Sex" column ="Sex" type="string" length="4" not-null="false"/>
        <property name="PersonID" column ="PersonID" type="string" length="30" not-null="false"/>
        <property name="Job" column ="Job" type="string" length="20" not-null="false"/>
        <property name="PlaceFrom" column ="PlaceFrom" type="string" length="10" not-null="false"/>
        <property name="Role" column ="Role" type="string" length="10" not-null="false"/>
        
      </class>
    </hibernate-mapping>
    变成<?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping   xmlns="urn:nhibernate-mapping-2.2"
        assembly="Model" namespace="Model">
      <class name ="Model.UserInfo,Model" table="BIWEILUN">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
          <generator class ="increment">      </generator>
        </id>
        
        
      </class>
    </hibernate-mapping>
    这样的效果我是这么做的            for(int i=0;i<propertyList.Count;i++)
                propertyList[i].RemoveAll();结果效果却是这样的:
    <?xml version="1.0" encoding="utf-8"?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model">
      <class name="Model.UserInfo,Model" table="BIWEILUN">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
          <generator class="increment">
          </generator>
        </id>
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
        <property />
      </class>
    </hibernate-mapping>
      

  14.   


            private void button1_Click(object sender, EventArgs e)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load("test.xml");
                XmlNodeList nodes = doc.SelectNodes("/*[local-name()='hibernate-mapping']/*[local-name()='class']/*[local-name()='property']");
                if (nodes.Count > 0 && nodes[0].ParentNode != null)
                {
                    XmlNode xnNew = nodes[0].Clone();
                    nodes[0].ParentNode.AppendChild(xnNew);
                    //怎么修改 xnNew 不需要说了吧? 
                    XmlElement xe = doc.CreateElement("", "property", "urn:nhibernate-mapping-2.2");
                    XmlAttribute xa = doc.CreateAttribute("name");
                    xa.Value = "role3";
                    xe.Attributes.Append(xa);
                    nodes[0].ParentNode.AppendChild(xe);
                }
                doc.Save("test_out.xml");            //remove
                nodes = doc.SelectNodes("/*[local-name()='hibernate-mapping']/*[local-name()='class']/*[local-name()='property']");            foreach (XmlNode xn in nodes)
                {
                    if (xn.ParentNode != null)
                    {
                        xn.ParentNode.RemoveChild(xn);
                    }
                }            doc.Save("test_out_2.xml");        }
      

  15.   


    XmlElement xe = xDoc.CreateElement("", "property", "urn:nhibernate-mapping-2.2");
                XmlAttribute[] xa = new XmlAttribute[5];            xa[0] = xDoc.CreateAttribute("name");
                xa[0].Value = "role3";
                xa[1] = xDoc.CreateAttribute("column");
                xa[1].Value = "role3";
                xa[2] = xDoc.CreateAttribute("type");
                xa[2].Value = "string";
                xa[3] = xDoc.CreateAttribute("length");
                xa[3].Value = "20";
                xa[4] = xDoc.CreateAttribute("not-null");
                xa[4].Value = "false";
                for (int i = 0; i < 5; i++)
                    xe.Attributes.Append(xa[i]);这样创建一个
    <property name="Role" column ="Role" type="string" length="10" not-null="false"/>
    这样的节点,代码会不会多了点?有没有好的 精简 写法?一下子5个属性全进去?感觉写的很繁琐...
      

  16.   

    楼上的也是对的
             
    //得到父节点
    XmlNode root = xmlFile.SelectSingleNode(xpath);
    //创建一个新的节点
    XmlElement selfElement = xmlFile.CreateElement("property");
    //设置节点属性
    selfElement.SetAttribute("name", "test");
    selfElement.SetAttribute("column", "col");
    //将节点挂到其父节点上
     root.AppendChild(selfElement);大概是以上这样子了,你调一下就可以了