当前位置: 首页 > 软件库 > 程序开发 > XML相关工具 >

Metah.X

XML 元编程语言
授权协议 MIT
开发语言 C#
所属分类 程序开发、 XML相关工具
软件类型 开源软件
地区 国产
投 递 者 丰智
操作系统 Windows
开源组织
适用人群 未知
 软件概览

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没有定型,欢迎提出修改意见。

XML Schema定义了XML数据(或叫XML实例)的形状及需要遵守的规则,比如下面的XSD代码:

<E1 xmlns="http://ns1">
  <E2 A1="123">abc</E2>
  <E3 xmlns="">
    <p:E4 xmlns:p="http://ns2" p:A1="true" A1="123" />
    def
  </E3>
</E1>

下面是合法的XML数据:

12345678-33487654321

因为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的内容:

12345678-33487654321

下面是d:\customer2.xml的内容:

12345678-3348765432111223344

也就是说,MX的用处 = XML Schema的用处 + Document Object Model的用处。

  • Metah.X(简称MX)用自创的语法实现了[url="http://www.w3.org/TR/xmlschema-1/"]XML Schema 1.0[/url]的语义,并且用C#实现了一个Schema-lized Document Object Model (SDOM),编译器编译MX代码后将生成使用SDOM的C#代码,这将XML Schema的语义映射到C#上,从而完全释放出XML Sch

 相关资料
  • 问题内容: 假设我有一个类似以下的查询: 如您所见,这两组之间的唯一区别是,在第一组中,我使用具有“ ONE”的列,在第二组中,具有“ TWO”的列,在我的实际查询中,我大约有30个这样的组,因此我想知道是否有某种方法可以缩短它? 问题答案: 由于它们是不同的列,因此必须在SELECT列表中分别明确提及它们。您不能在纯 SQL中 动态地执行此操作。 我建议使用一个好的 文本编辑器 ,几乎不需要一两

  • 技术的学习是一个登山的过程。第一章是最为平坦的山脚道路。而从这一章开始,则是正式的爬坡。无论是我写作还是你阅读,都需要付出比第一章更多的代价。那么问题就是,付出更多的精力学习模板是否值得? 这个问题很功利,但是一针见血。因为技术的根本目的在于解决需求。那C++的模板能做什么? 一个高(树)大(新)上(风)的回答是,C++里面的模板,犹如C中的宏、C#和Java中的自省(restropection)

  • 元编程 避免无谓的元编程。 当编写程序库时,不要使核心类混乱(不要使用 monkey patch)。 对于 class_eval 方法,倾向使用区块形式,而不是字符串插值形式。 当使用字符串插值形式时,总是提供 __FILE__ 及 __LINE__,以使你的调用栈看起来具有意义: class_eval 'def use_relative_model_naming?; true; end', __

  • Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyze or tran

  • Swift 是编写程序的绝佳选择,无论是手机、电脑还是服务器,任何能跑代码的设备都是如此。它是一门集现代语言之大成,集结了苹果的工程师文化精髓以及开源社区多样化于一身的编程语言。编译器为专为性能所调优,语言专为开发所优化,二者绝不互相妥协。

  • 明编程语言是一种简单快速的动态脚本语言。他支持以下特性 解释执行,不需要编译 动态参数类型,不需要设定参数类型 通过GC(垃圾收集器)自动管理内存分配和释放 面向对象 多重继承 操作符重载 提供数据构建操作符,方便复杂对象的创建 闭包与函数等价 多核/多线程优化 支持嵌入其他类型的文本文件(如HTML,XML) 支持用C/C++扩展 提供C API,可集成到其他程序中 明语言代码以GPL3发布。目

  • LIME 是一个使用类似 LISP 语法的动态编程语言 。 It features partial function application, eager and lazy evaluation, call-by-value and call-by-reference, macros, reading/writing LIME code as data, a standard library in

  • javascript元编程? 问题来自于codewars The builder of things 要求我们实现一个Thing类,其中一点要求如下所示: 难点是这里的name的值从哪里找啊? 我想到的一个方案是使用with,但是codewars上使用的是严格模式,不能使用with。