Metah.X: An XML Metaprogramming Language
Metah.X(简称MX)用自创的语法实现了XML Schema 1.0的语义,并且用C#实现了一个Schema-lized Document Object Model (SDOM),编译器编译MX代码后将生成使用SDOM的C#代码,这将XML Schema的语义映射到C#上,从而完全释放出XML Schema的力量。尽管现在只有C#版,实现Java版或其它语言版本是完全可能的。
MX是个开源项目,欢迎参与,比如实现Java版或其它语言版本;MX没有定型,欢迎提出修改意见。请访问:http://metah.codeplex.com/。
XML Schema定义了XML数据(或叫XML实例)的形状及需要遵守的规则,比如下面的XSD代码:
下面是合法的XML数据:
因为XSD相当繁琐不便于书写,MX自创了用户友好的语法来表达XML Schema的语义,下面的MX代码和上面的XSD代码表达了相同的语义:
MX编译器编译HelloWorld.mxcs后,将生成如下的C#代码:
使用编译器生成的代码,就可以创建、查询、修改、保存、装载及验证XML数据,下面的手写代码演示了如何使用编译器生成的代码:
下面是d:\customer.xml的内容:
下面是d:\customer2.xml的内容:
也就是说,MX的用处 = XML Schema的用处 + Document Object Model的用处。欲知详情,请访问:http://metah.codeplex.com/
MX是个开源项目,欢迎参与,比如实现Java版或其它语言版本;MX没有定型,欢迎提出修改意见。请访问:http://metah.codeplex.com/。
XML Schema定义了XML数据(或叫XML实例)的形状及需要遵守的规则,比如下面的XSD代码:
<?xml version="1.0" encoding="utf-8"?> <!--HelloWorld.xsd--> <schema targetNamespace="http://schemas.example.com/projecta" elementFormDefault="qualified" xmlns:tns="http://schemas.example.com/projecta" xmlns="http://www.w3.org/2001/XMLSchema"> <simpleType name="String20"> <restriction base="string"> <minLength value="1"></minLength> <maxLength value="20"></maxLength> </restriction> </simpleType> <simpleType name="PhoneCategory"> <restriction base="string"> <enumeration value="Unknown"></enumeration> <enumeration value="Work"></enumeration> <enumeration value="Home"></enumeration> </restriction> </simpleType> <complexType name="Phone"> <simpleContent> <extension base="tns:String20"> <attribute name="Category" use="optional" type="tns:PhoneCategory"></attribute> </extension> </simpleContent> </complexType> <complexType name="Customer"> <sequence> <element name="Phone" minOccurs="1" maxOccurs="unbounded" type="tns:Phone"></element> </sequence> <attribute name="Name" use="required" type="tns:String20"></attribute> <attribute name="Email" use="required"> <simpleType> <restriction base="tns:String20"> <pattern value="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}"></pattern> </restriction> </simpleType> </attribute> <attribute name="RegistrationDate" use="optional" type="dateTime"></attribute> </complexType> <element name="Customer" type="tns:Customer"></element> </schema>
下面是合法的XML数据:
<e0:Customer Name="Tank" Email="tank@example.com" RegistrationDate="2014-04-15T16:56:53.0568964Z" xmlns:e0="http://schemas.example.com/projecta"> <e0:Phone Category="Work">12345678-334</e0:Phone> <e0:Phone>87654321</e0:Phone> </e0:Customer>
因为XSD相当繁琐不便于书写,MX自创了用户友好的语法来表达XML Schema的语义,下面的MX代码和上面的XSD代码表达了相同的语义:
//HelloWorld.mxcs xnamespace {"http://schemas.example.com/projecta"} [namespace: Example.ProjectA] { type String20 restrict String facets { lengthrange: 1..20; }; ; type PhoneCategory restrict String facets{ enums: Unknown = "Unknown", Work = "Work", Home = "Home" }; ; type Phone extend String20 attributes { attribute Category[?] as PhoneCategory; }; ; type Customer attributes { attribute Name as String20; attribute Email as type restrict String20 facets { patterns: @"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}"; }; ; ; attribute RegistrationDate[?] as DateTime; }; children { element Phone[+; membername: Phones] as Phone; }; ; element Customer as Customer; }
MX编译器编译HelloWorld.mxcs后,将生成如下的C#代码:
//HelloWorld.mxcs.cs //Generated by MX compiler namespace Example.ProjectA { public partial class PhoneCategory : ... { public static readonly string @Unknown = "Unknown"; public static readonly string @Work = "Work"; public static readonly string @Home = "Home"; ... } public partial class Phone : ... { public partial class AttributeSetClass : ... { public string Category_Value { get; set; } ... } public AttributeSetClass AttributeSet { get; set; } public AttributeSetClass EnsureAttributeSet(); public string Value { get; set; } ... } public partial class Customer : ... { public partial class AttributeSetClass : ... { public string Name_Value { get; set; } public string Email_Value { get; set; } public DateTime? RegistrationDate_Value { get; set; } ... } public AttributeSetClass AttributeSet { get; set; } public AttributeSetClass EnsureAttributeSet(); public partial class ComplexChildClass : ... { public partial class Phones_Class : ... { public partial class ItemClass : ... { public Phone Type { get; set; } ... } public ItemClass CreateAndAddItem(); ... } public Phones_Class Phones { get; set; } public Phones_Class Ensure_Phones(); ... } public ComplexChildClass ComplexChild { get; set; } public ComplexChildClass EnsureComplexChild(); ... } public partial class Customer_ElementClass : ... { public Customer Type { get; set; } public static bool TryLoadAndValidate(XmlReader reader, Metah.X.Context context, out Customer_ElementClass result); ... } }
使用编译器生成的代码,就可以创建、查询、修改、保存、装载及验证XML数据,下面的手写代码演示了如何使用编译器生成的代码:
//Program.cs using System; using System.Xml;//for XmlReader & XmlWriter using X = Metah.X; namespace Example.ProjectA { class Program { static void Main(string[] args) { var customer = new Customer(); var cattset = customer.EnsureAttributeSet(); cattset.Name_Value = "Tank"; cattset.Email_Value = "tank@example.com"; cattset.RegistrationDate_Value = DateTime.Now; var phones = customer.EnsureComplexChild().Ensure_Phones(); var phone = phones.CreateAndAddItem(); phone.EnsureAttributeSet().Category_Value = PhoneCategory.Work; phone.Value = "12345678-334"; phones.CreateAndAddItem().Value = "87654321"; var customerElement = new Customer_ElementClass { Type = customer }; using (var writer = XmlWriter.Create(@"d:\customer.xml", new XmlWriterSettings { Indent = true })) customerElement.Save(writer); // var ctx = new X.Context(); using (var reader = XmlReader.Create(@"d:\customer.xml")) { Customer_ElementClass customerElement2; if (Customer_ElementClass.TryLoadAndValidate(reader, ctx, out customerElement2)) { var customer2 = customerElement2.Type; Console.WriteLine("Name={0}, Email={1}, RegistrationDate={2}", customer2.AttributeSet.Name_Value, customer2.AttributeSet.Email_Value, customer2.AttributeSet.RegistrationDate_Value); foreach (var phone2 in customer2.ComplexChild.Phones) { Console.WriteLine("\tCategory={0}, Value={1}", phone2.Type.AttributeSet.Category_Value, phone2.Type.Value); } customer2.AttributeSet.Name_Value += "-Knat"; customer2.AttributeSet.RegistrationDate = null; var phone3 = customer2.ComplexChild.Phones.CreateAndAddItem(); phone3.EnsureAttributeSet().Category_Value = PhoneCategory.Home; phone3.Value = "11223344"; using (var writer = XmlWriter.Create(@"d:\customer2.xml", new XmlWriterSettings { Indent = true })) customerElement2.Save(writer); } else { foreach (var diag in ctx.Diagnostics) Console.WriteLine(diag); } } } } }
下面是d:\customer.xml的内容:
<?xml version="1.0" encoding="utf-8"?> <e0:Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="e0:Customer" Name="Tank" Email="tank@example.com" RegistrationDate="2014-04-17T08:45:21.4460232Z" xmlns:e0="http://schemas.example.com/projecta"> <e0:Phone xsi:type="e0:Phone" Category="Work">12345678-334</e0:Phone> <e0:Phone xsi:type="e0:Phone">87654321</e0:Phone> </e0:Customer>
下面是d:\customer2.xml的内容:
<?xml version="1.0" encoding="utf-8"?> <e0:Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="e0:Customer" Name="Tank-Knat" Email="tank@example.com" xmlns:e0="http://schemas.example.com/projecta"> <e0:Phone xsi:type="e0:Phone" Category="Work">12345678-334</e0:Phone> <e0:Phone xsi:type="e0:Phone">87654321</e0:Phone> <e0:Phone xsi:type="e0:Phone" Category="Home">11223344</e0:Phone> </e0:Customer>
也就是说,MX的用处 = XML Schema的用处 + Document Object Model的用处。欲知详情,请访问:http://metah.codeplex.com/
相关推荐
Serving as a tutorial as well as a handbook for experts, this is the book on C++ template metaprogramming."Chuck Allison, Editor, The C++ Source C++ Template Metaprogramming sheds light on the most...
英文原版,元编程技术!英文原版,元编程技术!英文原版,元编程技术!
内容简介 本书是关于C++模板元编程的著作。本书主要介绍Traits和类型操纵、深入...附赠光盘内容包含所有Boost C++ 程序库:Boost Metaprogramming Library及其参考文件,还包含所有随书代码示例以及大量的补充材料。
Metaprogramming is one of Elixir's greatest features. Maybe you've played with the basics or written a few macros. Now you want to take it to the next level. This book is a guided series of ...
Soss.jl:通过源代码重写进行概率编程
ForceImport.jl:强制在模块中导入冲突方法的宏
Author Luciano Ramalho takes you through Python’s core language features and libraries, and shows you how to make your code shorter, faster, and more readable at the same time. Many experienced ...
template.scala:Scala中的C ++风味模板元编程
Reduce.jl:使用REDUCE代数术语重写器的Julia语言表达式的符号解析器生成器
C++.Template.Metaprogramming.-.companion.cd.rar
be aware of template metaprogramming. 8. 定制new和delete customizing new and delete 条款49:了解new-handler的行为 understand the behavior of the new-handler. 条款50:了解new和delete的合理替换时机 ...
Title: Learn C++ Programming Language: Become A Complete C++ Programmer Author: Virender Singh Length: 1018 pages Edition: 1 Language: English Publication Date: 2015-10-01 This Book Teaches C++ In ...
28. Metaprogramming ....................................................................... 779 29. A Matrix Design ......................................................................... 827 Part ...
Rubyinheritscharacteristicsfromvariouslanguages—Lisp,Small talk,C,andPerl,tonameafew.MetaprogrammingcomesfromLisp (andSmalltalk).It’sabitlikemagic,whichmakessomethingastonish ingpossible....
高清文字版,英文版,template、metatemplate学习。。
Helpers.js安装通过npm npm install @unisharp/helpers.js --save通纱yarn add @unisharp/helpers.js入门首先,将我们的babel插件添加到您的圣经配置中。 { "plugins": ["@unisharp/babel-plugin"]}然后要求主库进行...
Discovering Modern C++: An Intensive Course for Scientists, Engineers, and Programmers (C++ In-Depth Series) By 作者: Peter Gottschling ISBN-10 书号: 0134383583 ISBN-13 书号: 9780134383583 Edition ...
The C++ programming language / Bjarne Stroustrup.—Fourth edition. pages cm Includes bibliographical references and index. ISBN 978-0-321-56384-2 (pbk. : alk. paper)—ISBN 0-321-56384-0 (pbk. : alk. ...
The Go Programming Language is the authoritative resource for any programmer who wants to learn Go. It shows how to write clear and idiomatic Go to solve real-world problems. The book does not assume ...