數據字典生成工具之旅(3):PowerDesign文件組成結構介紹及操作


       從這篇開始將正式講解整個重要部分的實現細節,本篇講解Pdm文件的解析。其實PDM文件就是XML文件,可以用Editplus或者VS打開查看。了解到這一點之后大家就能猜到,可以用解析XML的方式讀取PDM文件了。

PDM文件結構及在本工具的存儲方式

        下面看看用Editplus讀取出來的XML,這里我只關注Table節點,這是一個表的最小節點了。  

          <o:Table Id="o97">
            <a:ObjectID>41144D16-B6B3-43CD-8B36-57CBAFB26654</a:ObjectID>
            <a:Name>預算資源面積月事實表</a:Name>
            <a:Code>y_FactYsRoomAreaMonth</a:Code>
            <a:CreationDate>1366118213</a:CreationDate>
            <a:Creator>huzhiwen</a:Creator>
            <a:ModificationDate>1396403208</a:ModificationDate>
            <a:Modifier>gongw</a:Modifier>
            <a:TotalSavingCurrency/>
            <c:Columns>
              <o:Column Id="o361">
                <a:ObjectID>F03D6EA9-183A-4B6A-BD52-7B711572AA45</a:ObjectID>
                <a:Name>ID</a:Name>
                <a:Code>ID</a:Code>
                <a:CreationDate>1366118213</a:CreationDate>
                <a:Creator>huzhiwen</a:Creator>
                <a:ModificationDate>1381212250</a:ModificationDate>
                <a:Modifier>huzw</a:Modifier>
                <a:DataType>bigint</a:DataType>
                <a:Identity>1</a:Identity>
                <a:Mandatory>1</a:Mandatory>
              </o:Column>
            </c:Columns>
            <c:Keys>
              <o:Key Id="o380">
                <a:ObjectID>F9089FCD-D9E9-4FB0-92F3-B7268D49526D</a:ObjectID>
                <a:Name>PK_Z_DIMROOMMONTH</a:Name>
                <a:Code>PK_Z_DIMROOMMONTH</a:Code>
                <a:CreationDate>1366118213</a:CreationDate>
                <a:Creator>huzhiwen</a:Creator>
                <a:ModificationDate>1366118213</a:ModificationDate>
                <a:Modifier>huzhiwen</a:Modifier>
                <c:Key.Columns>
                  <o:Column Ref="o361"/>
                </c:Key.Columns>
              </o:Key>
            </c:Keys>
            <c:PrimaryKey>
              <o:Key Ref="o380"/>
            </c:PrimaryKey>
            <c:ClusterObject>
              <o:Key Ref="o380"/>
            </c:ClusterObject>
          </o:Table>

       可以看到這些節點都是帶命名空間,所以我們解析這段XML的時候需要加上命名空間。表的<a:Name>(中文名稱),<a:Code>(表名),<c:Columns>是所有列節點集合,具體到每一列的<o:Column>則有中文名稱,英文名稱,主鍵,是否空,默認值,是否自增等關鍵信息了。
       參考上面的設計,添加了四個實體,ColumnInfo,TableInfo,PkKeyInfo,PhysicalDiagramInfo

      

PDM文件讀取

        1.加載XML    

   /// <summary>
        /// 讀取xml文件返回XmlDocument對象
        /// </summary>
        /// <returns>XmlDocument對象</returns>
        private XmlDocument GetXmlDom()
        {
            try
            {
                if (xmlDoc == null)
                {
                    StreamReader sr = new StreamReader(_pdmPath);
                    xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(ReplaceLowOrderASCIICharacters(sr.ReadToEnd()));                 
                }
                return xmlDoc;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
View Code

       2.設置XML的命名空間

 /// <summary>
        /// 設置xml文件命名空間
        /// </summary>
        /// <returns>XmlNamespaceManager</returns>
        private XmlNamespaceManager GetXmlNamespace()
        {
            XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(GetXmlDom().NameTable);
            xmlnsManager.AddNamespace("a", "attribute");
            xmlnsManager.AddNamespace("c", "collection");
            xmlnsManager.AddNamespace("o", "object");
            return xmlnsManager;
        }
View Code

       3.從中XML讀取表信息 

 /// <summary>
        /// 從中XML讀取表信息
        /// </summary>
        /// <returns> List</returns>
        public List<TableInfo> GetTableInfo()
        {
            try
            {
                XmlDocument xmlDoc = GetXmlDom();
                XmlNamespaceManager xmlnsManager = GetXmlNamespace();
                XmlNode xnTables = xmlDoc.SelectSingleNode("//" + "c:Tables", xmlnsManager);
                List<TableInfo> Tables = new List<TableInfo>();
                foreach (XmlNode xnTable in xnTables.ChildNodes)
                {
                    Tables.Add(GetTable(xnTable));
                }
                return Tables;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
View Code
        /// <summary>
        /// 獲取節點中表的信息
        /// </summary>
        /// <param name="xnTable">xmlNode</param>
        /// <returns>表信息</returns>
        private TableInfo GetTable(XmlNode xnTable)
        {
            try
            {
                TableInfo mTable = new TableInfo();
                XmlElement xe = (XmlElement)xnTable;
                mTable.TableID = xe.GetAttribute("Id");
                XmlNodeList xnTProperty = xe.ChildNodes;
                foreach (XmlNode xnP in xnTProperty)
                {
                    switch (xnP.Name)
                    {
                        //表的ID
                        case "a:ObjectID":
                            mTable.TableObjectID = xnP.InnerText;
                            break;
                        //表的中文名稱
                        case "a:Name":
                            mTable.Name = xnP.InnerText;
                            break;
                        //表的英文名稱
                        case "a:Code":
                            mTable.Code = xnP.InnerText;
                            break;
                        //表的描述
                        case "a:Comment":
                            mTable.Comment = xnP.InnerText;
                            break;
                        //表的列信息
                        case "c:Columns":
                            InitColumns(xnP, mTable);
                            break;
                        //表的主鍵信息
                        case "c:Keys":
                            InitKeys(xnP, mTable);
                            break;
                        default:
                            break;
                    }
                }
                if (string.IsNullOrEmpty(mTable.Comment))
                {
                    mTable.Comment = mTable.Name;
                }
                if (mTable.ListPkKeyInfo != null && mTable.ListPkKeyInfo.Count > 0)
                {
                    foreach (PkKeyInfo pkInfo in mTable.ListPkKeyInfo)
                    {
                        ColumnInfo info = mTable.ListColumnInfo.Single(c => c.ColumnId == pkInfo.ColumnId);
                        pkInfo.Name = info.Code;
                        info.PK = true;
                        mTable.PkKeyNameList = mTable.PkKeyNameList + pkInfo.Name + ",";
                    }
                }
                //杜冬軍2014-05-16 修改沒有主鍵  生成SQL有問題的BUG  V1.4
                else
                {
                    mTable.ListPkKeyInfo=new List<PkKeyInfo>();
                }
                if (!string.IsNullOrEmpty(mTable.PkKeyNameList))
                {
                    mTable.PkKeyNameList = mTable.PkKeyNameList.Substring(0, mTable.PkKeyNameList.Length - 1);
                }
                return mTable;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
View Code

       4.讀取列信息 

  /// <summary>
        /// 獲取列信息
        /// </summary>
        /// <param name="xnColumn">列節點</param>
        /// <returns>列信息</returns>
        private ColumnInfo GetColumn(XmlNode xnColumn)
        {

            ColumnInfo mColumn = new ColumnInfo();
            XmlElement xe = (XmlElement)xnColumn;
            mColumn.ColumnId = xe.GetAttribute("Id");
            XmlNodeList xnCProperty = xe.ChildNodes;
            foreach (XmlNode xnP in xnCProperty)
            {
                switch (xnP.Name)
                {
                    //列ID
                    case "a:ObjectID":
                        mColumn.ColumnObjectId = xnP.InnerText;
                        break;
                    //列中文名稱
                    case "a:Name":
                        mColumn.Name = xnP.InnerText;
                        break;
                    //列英文名稱
                    case "a:Code":
                        mColumn.Code = xnP.InnerText;
                        break;
                    //列描述
                    case "a:Comment":
                        mColumn.Comment = xnP.InnerText;
                        break;
                    //列數據類型
                    case "a:DataType":
                        mColumn.DataTypeStr = xnP.InnerText.Replace("", "(").Replace("", ")");
                        mColumn.DataType = Common.GetColumnDataType(mColumn.DataTypeStr);
                        mColumn.Width = Common.GetColumnWidth(mColumn.DataTypeStr);
                        break;
                    //列寬度
                    case "a:Length":
                        mColumn.Length = xnP.InnerText;
                        break;
                    //列是否自增
                    case "a:Identity":
                        mColumn.Identity = Common.ConvertToBooleanPG(xnP.InnerText);
                        break;
                    //列默認值
                    case "a:DefaultValue":
                        mColumn.DefaultValue = xnP.InnerText;
                        break;
                    //列是否可為空
                    case "a:Mandatory":
                        mColumn.Nullable = Common.ConvertToBooleanPG(xnP.InnerText);
                        break;
                    default:
                        break;
                }
            }
            if (string.IsNullOrEmpty(mColumn.Comment))
            {
                mColumn.Comment = mColumn.Name;
            }
            if (string.IsNullOrEmpty(mColumn.DefaultValue))
            {
                mColumn.DefaultValue = "";
            }
            return mColumn;
        }       
View Code

    其它信息操作可以查看源代碼里面的PDMReader.cs文件

 

XML文件操作增刪改查

       PDM文件操作完畢,大家可以發現歸根到底就是XML的增刪改查操作,讀取XML文件用Xpth比較方便。

       我做了一個小例子供大家參考:XmlDemo

 public void Read()
        {
            XmlNodeList xmlNodeList = null;
            xmlNodeList = XmlDoc.SelectNodes("/root/item");
            Console.WriteLine("遍歷item節點");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                Console.WriteLine("item節點的RoomInfo屬性讀取:{0}", xmlNode.Attributes["RoomInfo"].Value);
                Console.WriteLine("item節點的RoomInfo的值讀取:{0}", xmlNode.InnerText);
            }
            Console.WriteLine("遍歷items下的item節點");
            xmlNodeList = XmlDoc.SelectNodes("/root/items/item");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                Console.WriteLine("item節點的RoomInfo屬性讀取:{0}", xmlNode.Attributes["RoomInfo"].Value);
                Console.WriteLine("item節點的RoomInfo的值讀取:{0}", xmlNode.InnerText);
            }
            Console.WriteLine("遍歷第一個items下的item節點");
            xmlNodeList = XmlDoc.SelectNodes("/root/items[@id='item1']/item");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                Console.WriteLine("item節點的RoomInfo屬性讀取:{0}", xmlNode.Attributes["RoomInfo"].Value);
                Console.WriteLine("item節點的RoomInfo的值讀取:{0}", xmlNode.InnerText);
            }
            Console.WriteLine("遍歷第二個items下的Group下的item節點");
            xmlNodeList = XmlDoc.SelectNodes("/root/items[@id='item2']/Group[@id='g1']/item");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                Console.WriteLine("item節點的RoomInfo屬性讀取:{0}", xmlNode.Attributes["RoomInfo"].Value);
                Console.WriteLine("item節點的RoomInfo的值讀取:{0}", xmlNode.InnerText);
            }
        }
View Code
  public void Update()
        {
            Console.WriteLine("修改所有的item節點RoomInfo的屬性的值為123");
            XmlNodeList xmlNodeList = null;
            xmlNodeList = XmlDoc.SelectNodes("/root/item");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                xmlNode.Attributes["RoomInfo"].Value = "123";
            }
            Console.WriteLine("修改所有的item節點的值為123");
            xmlNodeList = XmlDoc.SelectNodes("/root/item");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                xmlNode.InnerText = "123";
            }
            Console.WriteLine(XmlDoc.InnerXml);
        }
View Code
 public void Delete()
        {
            Console.WriteLine("刪除所有的item節點");
            XmlNodeList xmlNodeList = null;
            xmlNodeList = XmlDoc.SelectNodes("/root/item");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                xmlNode.ParentNode.RemoveChild(xmlNode);
            }
            Console.WriteLine("刪除所有的items下的子節點");
            xmlNodeList = XmlDoc.SelectNodes("/root/items");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                xmlNode.RemoveAll();
            }
            Console.WriteLine(XmlDoc.InnerXml);
        }
View Code
public void Add()
        {
            Console.WriteLine("item節點添加test=123屬性");
            XmlNodeList xmlNodeList = null;
            XmlAttribute xmlAttribute = null;
            xmlNodeList = XmlDoc.SelectNodes("/root/item");
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                xmlAttribute = XmlDoc.CreateAttribute("test");
                xmlAttribute.Value = "123";
                xmlNode.Attributes.Append(xmlAttribute);
            }
            Console.WriteLine("item節點添加子節點<test name='123'>");
            xmlNodeList = XmlDoc.SelectNodes("/root/item");
            XmlElement xmlNewNode = null;
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                xmlNewNode = XmlDoc.CreateElement("test");
                xmlNewNode.SetAttribute("name", "123");
                xmlNewNode.InnerText = "123";
                xmlNode.AppendChild(xmlNewNode);
            }
            XmlDoc.Save("C:\\123.xml");
            Console.WriteLine(XmlDoc.InnerXml);
        }
View Code

 

 

工具源代碼下載

      目前總共有經過了七個版本的升級,現在提供最新版本的下載地址

數據字典生成工具V2.0安裝程序 最新安裝程序
數據字典生成工具源代碼 最新源代碼
http://code.taobao.org/svn/DataDicPub SVN最新源碼共享地址

學習使用

      如果你使用了該工具,或者想學習該工具,歡迎加入這個小組,一起討論數據字典生成工具、把該工具做的更強,更方便使用,一起加入147425783 QQ群

      更多數據字典生成工具資料請點擊數據字典生成工具專題

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM