




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
TinyXML入门教程 收藏 TinyXML入门教程 文章分类:C+ 编程 TinyXML 入门教程什么是XML ? 1文档类 2创建文档对象 3输出文档对象 3保存文档对象 4返回第一个根元素 5声明类 5注释类 6元素类 6节点名 6父节点 6子节点 7编辑子节点 7同级节点 7遍历元素 8元素属性 8元素函数总结 9属性类 10 文章下载 源代码下载 什么是 XML ? XML 全称EXtensible Markup Language ,翻译为可扩展标记语言,简而言之就是你可以自定义数据的标识, 以此来区分各种不同的数据, 以便于进行数据交换, 例如html 就可以理解 为一种简单的xml 语言。XML 文件通常就是一个文本文件, 可以使用任何编码 上图就是我系统中一个xml 文件的图标,使用VC2005 打开它,你可以看到如下内容: XML 也是有这几个对象组成了,一般来说我们经常使用的类如下:l TiXmlDocument :文档类,它代表了整个xml 文件。l TiXmlDeclaration :声明类,它表示文件的声明部分,如上图所示。l TiXmlComment :注释类,它表示文件的注释部分,如上图所示。l TiXmlElement :元素类,它是文件的主要部分,并且支持嵌套结构,一般使用这种结构来分类的存储信息,它可以包含属性类和文本类,如上图所示。n TiXmlAttribute/TiXmlAttributeSet :元素属性,它一般嵌套在元素中,用于记录此元素的一些属性,如上图所示。n TiXmlText :文本对象,它嵌套在某个元素内部,如上图所示。 TinyXml 使用文档对象模型(DOM )来解析xml 文件,这种模型的处理方式为在分析时,一次性的将整个XML 文档进行分析,并在内存中形成对应的树结构,同时,向 用户提供一系列的接口来访问和编辑该树结构。这种方式占用内存大,但可以给用户提供一个面向对象的访问接口,对用户更为友好,非常方便用户使用。下面我们依次来介绍各个类的用法。 文档类 文档类代表一个XML 文档,通过它,你可以保存, 载入和打印输出文档。你可以通过以下方式载入xml 文档到TiXmlDocument 。 创建文档对象 l 创建一个空的文档对象,然后载入一个xml 文档使用到的函数原形如下:+TiXmlDocument();+bool LoadFile( const std:string& filename)在程序中你可以如下使用:/ 载入xml 文档TiXmlDocument doc();doc.LoadFile(tutorial.xml); l 2 、在构造函数中传入文档的名称,然后调用load 函数完成解析载入使用到的函数原形如下:+TiXmlDocument( const std:string& documentName );+bool LoadFile();在程序中你可以如下使用:/ 载入xml 文档TiXmlDocument doc(tutorial.xml);doc.LoadFile(); 输出文档对象 文档类提供了Print() 函数用于在控制台输出当前的文档内容,这个函数的原形如下:+void Print() const在程序中你可以如下使用:/ 载入xml 文档TiXmlDocument doc(tutorial.xml);doc.LoadFile();doc.Print(); / 输出文档 tutorial.xml 的内容如下: This a text( 这是一个文本) 在控制台中你可以得到如下输出: 由于文件使用 UTF-8 编码,而 Windows 下的控制台默认使用 gb2312 编码,因此会生成乱码。 保存文档对象 当然你也可以使用 SaveFile() 函数来进行另存为,这个函数的原形如下: bool SaveFile( const std:string& filename ) const在程序中你可以如下使用: / 载入 xml 文档 TiXmlDocument doc(tutorial.xml);doc.LoadFile();doc.Print(); / 输出文档 coutendl;doc.SaveFile(tutorial.txt); 使用记事本打开 tutorial.txt ,你可以看到如下内容。 返回第一个根元素 另外文档对象还提供了一个实用的函数用于返回第一个根对象,它可以让你方便的遍历整个文档结构,查找自己需要的数据。函数原形如下: +TiXmlElement* RootElement()我们在介绍元素类的时候再详细介绍它的使用。 声明类 在标准的 XML 文件中,声明为文件的第一项,例如 , 声明对象具有三个属性值,版本,编码和独立文件声明 一般来说文档的第一行就是声明对象,你可以把文档对象的第一个子节点转换为声明对象。 / 使用 TinyXml 的声明对象 TiXmlDeclaration *decl;decl = doc.FirstChild()-ToDeclaration(); 然后就可以使用它的功能了,它可以让你返回当前的版本,编码等信息,函数原形如下: +const char *Version() const+const char *Encoding() const+const char *Standalone() const 在程序中你可以如下使用: / 使用 TinyXml 的声明对象 TiXmlDeclaration *decl;decl = doc.FirstChild()-ToDeclaration();cout 使用 TinyXml 的声明对象 (TiXmlDeclaration)Print(0,4,&str);coutstrendl;/ 分别输出声明对象的属性 cout 版本: Version() 是否为对立文件: Standalone() 编码方式: Encoding()endl;coutendl; 注释类 这个类一般为 xml 数据提供解释说明,在程序中一般不使用它,因此,这里就不介绍了。 元素类 元素为一个容器类,它具有元素名称,并可以包含其它元素,文本,注释和未知节点,这些对象统称为元素的节点,即节点可以为元素、文本、注释和未知节点类型。元素也可以包含任意个数的属性。 我们还是以如下的 XML 代码来说明这个类的功能。 This a text( 这是一个文本 ) 节点名 在上方元素的代码中, element 为根元素的名称,你可以通过如下的函数来设置和返回它。 +const std:string& ValueStr() const+void SetValue( const std:string& _value ) 父节点 subelement1 , subelement2 , subelement3 , subelement4 都是 element 的子元素,如果当前元素对象的指针指向 subelement1 , subelement2 , subelement3 , subelement4 ,你可以通过 Parent() 函数来返回指向 element 对象的指针, Parent() 函数的声明如下: +TiXmlNode* Parent() 子节点 通过父节点的指针,你可以遍历所有的子节点。 +TiXmlNode* FirstChild()+TiXmlNode* FirstChild( const std:string& _value )上面两个函数用于返回第一个子节点对象的指针,带参数名的那个函数表示返回第一个名为 _value 的子节点。 +TiXmlNode* LastChild()+TiXmlNode* LastChild( const std:string& _value )上面的两个函数用于返回最后一个节点对象的指针,带参数名的那个函数表示返回最后一个名为 _value 的子节点。 你也可以使用 IterateChildren() 函数来依次遍历所有的节点,它们的函数声明如下: +TiXmlNode* IterateChildren( const TiXmlNode* previous )+TiXmlNode* IterateChildren( const std:string& _value, const TiXmlNode* previous )带参数名的那个函数表示只遍历同名的节点。 编辑子节点 你可以插入、删除替换所有的子节点。 +TiXmlNode* InsertEndChild( const TiXmlNode& addThis );+TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );+TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );上面三个函数用于插入节点, InsertEndChild 函数让你把新节点插入到末尾, InsertBeforeChild 和 InsertAfterChild 函数允许你在指定的节点位置前后插入节点。 +TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );ReplaceChild 函数用于替换指定的节点。 +bool RemoveChild( TiXmlNode* removeThis );RemoveChild 函数让你删除指定的节点。 void Clear();Clear 函数会删除本节点的所有子节点(包括子节点包含的从子节点),但不会修改本节点。 同级节点 This a text( 这是一个文本 ) 在上面的 xml 代码中, subelement1 、 subelement2 、 subelement3 、 subelement4 都属于同级节点,我们也提供了相关的函数用于在这些同级节点中遍历。 +TiXmlNode* PreviousSibling()+TiXmlNode* PreviousSibling( const std:string& _value )可以根据当前的节点,返回上一个节点的指针。带参数名的那个函数表示返回上一个名为 _value 的节点。 当然你也可以根据当前的节点,返回下一个节点的指针。带参数名的那个函数表示返回下一个名为 _value 的节点。 +TiXmlNode* NextSibling()+TiXmlNode* NextSibling( const std:string& _value) 遍历元素 元素是一种特殊的节点,以 为开始字符,后接元素名称。函数 NextSiblingElement 用于返回下一个同级元素,而忽略其它类型的节点。它们的函数声明如下: +TiXmlElement* NextSiblingElement()+TiXmlElement* NextSiblingElement( const std:string& _value)带参数名的那个函数表示返回下一个名为 _value 的同级元素。 本类也提供了相关的函数,让你返回第一个子元素。 +TiXmlElement* FirstChildElement()+TiXmlElement* FirstChildElement( const std:string& _value )带参数名的那个函数表示返回下一个名为 _value 的子元素。 元素属性 属性一般保存在元素中,它们为使用 “=” 号连接的两个字符串,左边的表示属性名,等号右边的表示属性值,通常使用字符串、整数和浮点数等数据类型表示。例如, pi = 3.14 。 你可以通过如下的函数,返回属性值。 +const std:string* Attribute( const std:string& name ) const;+const std:string* Attribute( const std:string& name, int* i ) const;+const std:string* Attribute( const std:string& name, double* d ) const;在上面 3 个函数中,第一个函数使用字符串保存返回的属性值,第二个函数把属性值转换为整数然后返回,第三个函数把属性值转换为浮点数然后返回。不过,第二、三个函数都会以字符串的形式记录属性值,并作为函数的返回值返回。 另外,你也可以使用模板函数: +template int QueryValueAttribute( const std:string& name, T* outValue ) const来返回特点的属性值,它会根据你传入的参数,自动选择合适数据类型。 另外,本类也提供了如下三个函数让你设置属性,参数的类型和返回函数类似。 +void SetAttribute( const std:string& name, const std:string& _value );+void SetAttribute( const std:string& name, int _value );+void SetDoubleAttribute( const char * name, double value ); FirstAttribute 和 LastAttribute 可以让你返回第一个和最后一个属性,它们的函数声明如下: +TiXmlAttribute* FirstAttribute()+TiXmlAttribute* LastAttribute() RemoveAttribute 函数可以让你删除指定名称的属性,它的函数声明如下: +void RemoveAttribute( const std:string& name ) 元素函数总结 ValueStr / 返回元素名称SetValue / 设置元素名称Parent / 返回父节点对象 FirstChild / 返回第一个子节点LastChild / 返回最后一个子节点IterateChildren / 返回下一个子节点 InsertEndChild / 在最后一个子节点后插入子节点InsertBeforeChild / 在指定的子节点前插入子节点InsertAfterChild / 在指定的子节点后插入子节点ReplaceChild / 替换指定的子节点RemoveChild / 删除指定的子节点Clear / 删除所有的子节点 PreviousSibling / 返回同级中前一个节点NextSibling / 返回同级中后一个节点 NextSiblingElement / 返回同级中后一个元素FirstChildElement / 返回第一个子元素节点Attribute / 返回元素中的属性值QueryValueAttribute / 返回元素中的属性值SetAttribute / 设置元素中的属性值FirstAttribute / 返回元素中第一个属性对象LastAttribute / 返回元素中最后一个属性对象RemoveAttribute / 删除元素中指定的属性对象 属性类 属性为名称 = 值 对,元素可以具有属性值,但名称必须唯一。 你可以通过 +const std:string& NameTStr() const返回属性名称 也可以通过下面三个函数返回属性值: +const std:string& ValueStr() const+int IntValue() const;+double DoubleValue() const; 当然你也可以设置属性值,它们的函数声明如下: +void SetName( const std:string& _name )+void SetIntValue( int _value ); +void SetDoubleValue( double _value );+void SetValue( const std:string& _value )以上函数与元素类中的相关函数类似,这里不重复介绍了。 在元素属性中,通常具有许多属性,你可以通过 Next 函数返回下一个属性对象的指针,也可以通过 Previous 函数获得上一个属性对象的指针。它们的函数声明如下: +TiXmlAttribute* Next()+TiXmlAttribute* Previous() TinyXml介绍TinyXml是一个基于DOM模型的、非验证的轻量级C+解释器一. XML解析模型:目前XML的解析主要有两大模型:SAX和DOM。SAX是基于事件的,其基本工作流程是分析XML文档,当发现了一个新的元素时,产生一个对应事件,并调用相应的用户处理函数。这种方式占用内存少,速度快,但用户程序相应得会比较复杂。DOM(文档对象模型),则是在分析时,一次性的将整个XML文档进行分析,并在内存中形成对应的树结构,同时,向用户提供一系列的接口来访问和编辑该树结构。这种方式占用内存大,速度往往慢于SAX,但可以给用户提供一个面向对象的访问接口,对用户更为友好。另据说,一些同时提供了SAX和DOM接口的库,是在底层先实现SAX,再在SAX的基础上实现DOM对于一个特定的XML文档而言,其正确性分为两个层次。首先是其格式应该符合XML的基本格式要求,比如第一行要有声明,标签的嵌套层次必须前后一致等等,符合这些要求的文件,就是一个合格的XML文件,称作well-formatted。其次,一个XML文档因其内容的不同还必须在语义上符合相应的标准,这些标准由相应的DTD文件或者Schema文件来定义,符合了这些定义要求的XML文件,称作valid。因此,解析器也分为两种,一种是验证的,即会跟据XML文件中的声明,用相应的DTD文件对XML文件进行校验,检查它是否满足DTD文件的要求。另一种是忽略DTD文件,只要基本格式正确,就可以进行解析。就我所知,验证的解析器通常都是比较重量级的。TinyXml不支持验证,但是体积很小,用在解析格式较为简单的XML文件,比如配置文件时,特别的合适。二. TinyXml 介绍:Tiny Xml Online DocumentationTinyXml Class HierarchyThis inheritance list is sorted roughly, but not completely, alphabetically:TiXmlBaseTiXmlAttributeTiXmlNodeTiXmlCommentTiXmlDeclarationTiXmlDocumentTiXmlElementTiXmlTextTiXmlUnknownTiXmlHandleTiXmlVisitorTiXmlPrinterTinyXml实现的时DOM访问模型,因此提供了一系列的类对应XML文件中的各个节点。主要类间的关系如下图所示:TiXmlBase:其他类的基类,是个抽象类TiXmlNode:表示一个节点,包含节点的一般方法,如访问自节点、兄弟节点、编辑自身、编辑子节电TiXmlDocument:表示整个XML文档,不对应其中某个特定的节点。TiXmlElement:表示元素节点,可以包含子节点和TiXmlAttributeTiXmlComment:表示注释TiXmlDeclaration:表示声明TiXmlText:表示文本节点TiXmlUnknown:表示未知节点,通常是出错了TiXmlAttribute:表示一个元素的属性各类之间的转换由于各个节点类都从TiXmlNode继承,在使用时常常需要将TiXmlNode*类型的指针转换为其派生类的指针,在进行这种转换时,应该首先使用由 TiXmlNode类提供的一系列转换函数,如ToElement(void),而不是c+的dynamic_cast检查返回值由于TinyXml是一个非校验的解析器,因此当解析一个文件时,很可能文件并不包含我们预期的某个节点,在这种情况下,TinyXml将返回空指针。因此,必须要对返回值进行检查,否则将很容易出现内存访问的错误。如何重头建立一个XML文件先建立一个TiXmlDocument对象,然后,载入某个模板,或者直接插入一个节点作为根节点,接着就可以像打开一个已有的XML文件那样对它进行操作了。三. TinyXml 实践:Linux: Makefile setting# DEBUG can be set to YES to include debugging info, or NO otherwiseDEBUG := YES# PROFILE can be set to YES to include profiling info, or NO otherwisePROFILE := NO# TINYXML_USE_STL can be used to turn on STL support. NO, then STL# will not be used. YES will include the STL files.TINYXML_USE_STL := YESTinyXml在构建时可以选择是否支持STL,选择的话,则可以使用std:string,所以通常应该打开这个选项。在Windows上,TinyXml的源码包里提供了VC6的工程文件,直接用它就可以生成两个静态库(带STL和不带STL),非常容易。唯一需要注意的是,默认生成的库是单线程的,如果用在多线程的项目中,需要改动一下配置,生成相应的多线程库。构建了相应的库之后,在使用了它们的工程中,只要在连接时把他们连上就行了。需要注意的是,如果需要STL支持,在编译用到了TinyXml的文件时,需 要定义一个宏TIXML_USE_STL,对gcc,可以使用参数-DTIXML_USE_STL,对cl.exe(VC),可以使用参数 /DTIXML_USE_STL,如果嫌麻烦,可以直接定义在 tinyxml.h文件里。附件: pro四. 例程:引自: /phinecos/archive/2008/03/11/1100912.htmlCpp代码 1. #include 2. #includetinyxml.h 3. #includetinystr.h 4. #include 5. #include 6. #include 7. usingnamespacestd; 8. 9. CStringGetAppPath() 10. /获取应用程序根目录 11. 12. TCHARmodulePathMAX_PATH; 13. GetModuleFileName(NULL,modulePath,MAX_PATH); 14. CStringstrModulePath(modulePath); 15. strModulePath=strModulePath.Left(strModulePath.ReverseFind(_T(); 16. returnstrModulePath; 17. 18. 19. boolCreateXmlFile(string&szFileName) 20. /创建xml文件,szFilePath为文件保存的路径,若创建成功返回true,否则false 21. 22. try23. 24. /创建一个XML的文档对象。 25. 26. TiXmlDocument*myDocument=newTiXmlDocument(); 27. /创建一个根元素并连接。 28. 29. TiXmlElement*RootElement=newTiXmlElement(Persons); 30. myDocument-LinkEndChild(RootElement); 31. /创建一个Person元素并连接。 32. 33. TiXmlElement*PersonElement=newTiXmlElement(Person); 34. RootElement-LinkEndChild(PersonElement); 35. /设置Person元素的属性。 36. 37. PersonElement-SetAttribute(ID,1); 38. /创建name元素、age元素并连接。 39. 40. TiXmlElement*NameElement=newTiXmlElement(name); 41. TiXmlElement*AgeElement=newTiXmlElement(age); 42. PersonElement-LinkEndChild(NameElement); 43. PersonElement-LinkEndChild(AgeElement); 44. /设置name元素和age元素的内容并连接。 45. 46. TiXmlText*NameContent=newTiXmlText(周星星); 47. TiXmlText*AgeContent=newTiXmlText(22); 48. NameElement-LinkEndChild(NameContent); 49. AgeElement-LinkEndChild(AgeContent); 50. CStringappPath=GetAppPath(); 51. stringseperator=; 52. stringfullPath=appPath.GetBuffer(0)+seperator+szFileName; 53. myDocument-SaveFile(fullPath.c_str();/保存到文件 54. 55. 56. catch(string&e) 57. 58. returnfalse; 59. 60. returntrue; 61. 62. 63. boolReadXmlFile(string&szFileName) 64. /读取Xml文件,并遍历 65. 66. try67. 68. CStringappPath=GetAppPath(); 69. stringseperator=; 70. stringfullPath=appPath.GetBuffer(0)+seperator+szFileName; 71. /创建一个XML的文档对象。 72. 73. TiXmlDocument*myDocument=newTiXmlDocument(fullPath.c_str(); 74. myDocument-LoadFile(); 75. /获得根元素,即Persons。 76. 77. TiXmlElement*RootElement=myDocument-RootElement(); 78. /输出根元素名称,即输出Persons。 79. 80. coutValue()FirstChildElement(); 84. /获得第一个Person的name节点和age节点和ID属性。 85. 86. TiXmlElement*NameElement=FirstPerson-FirstChildElement(); 87. TiXmlElement*AgeElement=NameElement-NextSiblingElement(); 88. TiXmlAttribute*IDAttribute=FirstPerson-FirstAttribute(); 89. /输出第一个Person的name内容,即周星星;age内容,即;ID属性,即。 90. 91. coutFirstChild()-Value()endl; 92. coutFirstChild()-Value()endl; 93. coutValue()endl; 94. 95. catch(string&e) 96. 97. returnfalse; 98. 99. returntrue; 100. 101. intmain() 102. 103. stringfileName=info.xml; 104. CreateXmlFile(fileName); 105. ReadXmlFile(fileName); 106. 107. #include #include tinyxml.h#include tinystr.h#include #include #include using namespace std;CString GetAppPath()/获取应用程序根目录TCHAR modulePathMAX_PATH;GetModuleFileName(NULL, modulePath, MAX_PATH);CString strModulePath(modulePath);strModulePath = strModulePath.Left(strModulePath.ReverseFind(_T();return strModulePath;bool CreateXmlFile(string& szFileName)/创建xml文件,szFilePath为文件保存的路径,若创建成功返回true,否则falsetry/创建一个XML的文档对象。TiXmlDocument *myDocument = new TiXmlDocument();/创建一个根元素并连接。TiXmlElement *RootElement = new TiXmlElement(Persons);myDocument-LinkEndChild(RootElement);/创建一个Person元素并连接。TiXmlElement *PersonElement = new TiXmlElement(Person);RootElement-LinkEndChild(PersonElement);/设置Person元素的属性。PersonElement-SetAttribute(ID, 1);/创建name元素、age元素并连接。TiXmlElement *NameElement = new TiXmlElement(name);TiXmlElement *AgeElement = new TiXmlElement(age);PersonElement-LinkEndChild(NameElement);PersonElement-LinkEndChild(AgeElement);/设置name元素和age元素的内容并连接。TiXmlText *NameContent = new TiXmlText(周星星);TiXmlText *AgeContent = new TiXmlText(22);NameElement-LinkEndChild(NameContent);AgeElement-LinkEndChild(AgeContent);CString appPath = GetAppPath();string seperator = ;string fullPath = appPath.GetBuffer(0) +seperator+szFileName;myDocument-SaveFile(fullPath.c_str();/保存到文件catch (string& e)return false;return true;bool ReadXmlFile(string& szFileName)/读取Xml文件,并遍历tryCString appPath = GetAppPath();string seperator = ;string fullPath = appPath.GetBuffer(0) +seperator+szFileName;/创建一个XML的文档对象。TiXmlDocument *myDocument = new TiXmlDocument(fullPath.c_str();myDocument-LoadFile();/获得根元素,即Persons。TiXmlElement *RootElement = myDocument-RootElement();/输出根元素名称,即输出Persons。cout Value() FirstChildElement();/获得第一个Person的name节点和age节点和ID属性。TiXmlElement *NameElement = FirstPerson-FirstChildElement();TiXmlElement *AgeElement = NameElement-NextSiblingElement();TiXmlAttribute *IDAttribute = FirstPerson-FirstAttribute()
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 文化产业推动经济新动能
- Leucomycin-A6-生命科学试剂-MCE
- 2025年中期美股策略观点:溢价收敛龙头为先
- 农业农村土地制度改革与土地流转政策研究报告
- 量子密钥分发在工业互联网平台中的数据加密效率优化报告
- 金融行业数据治理与隐私保护在金融大数据分析中的应用报告
- 文化艺术中心建筑2025年初步设计可持续发展评估报告
- 2025年农业绿色生产模式与新型农业经营主体培育策略研究报告
- 工业互联网平台安全多方计算在智能制造领域的应用案例分析报告
- 基于监管视角的美国次贷危机成因分析及其对我国的启示
- 国开作业《公共关系学》实训项目3:社区关系建设(六选一)-实训项目二社区关系建设方案-参考(含答案)98
- 《历史文化名城名镇名村保护规划编制要求》
- 现场工程量确认单
- 《数据科学与大数据技术导论》完整版课件(全)
- 2022年广东省佛山市顺德区承德小学小升初数学试卷
- 申请人申请仲裁送达信息确认书
- 黄亮和李燕的创业故事(凤山书屋)
- (完整版)生物同源性荷尔蒙替代疗法课件
- 福建跨学科四门主干课程作业及答案小学语文
- 燃气输配课程设计报告书
- DB61∕T 5006-2021 人民防空工程标识标准
评论
0/150
提交评论