• 数据字典生成工具之旅(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群

          更多数据字典生成工具资料请点击数据字典生成工具专题

  • 相关阅读:
    JavaWeb:ServletRequestListener
    JavaWeb:HttpServletRequestWrapper
    JavaWeb:Filter
    JavaWeb:HttpSession
    对APS的简单了解
    rem,px,em最大的区别;
    使用vue-cli构建工具构建vue项目时候组件的使用
    webpack 4.0 配置方法以及错误解决
    px,rem,em 通过媒体查询统一的代码
    关于页面中css某些情况下出现不知原因的隔断解决办法
  • 原文地址:https://www.cnblogs.com/yanweidie/p/3841575.html
Copyright © 2020-2023  润新知