第三十章 从类生成XML架构

第三十章 从类生成XML架构

本章介绍如何使用%XML.Schema从启用了XML的类生成XML架构。

概述

要生成为同一XML命名空间中的多个类定义类型的完整架构,请使用%XML.Schema构建架构,然后使用%XML.Writer为其生成输出。

从多个类构建架构

要构建XML架构,请执行以下操作:

  1. 创建%XML.Schema实例。
  2. 可以选择设置实例的属性:
  • 若要为任何其他未分配的类型指定命名空间,请指定DefaultNamespace属性。默认值为NULL
  • 默认情况下,类及其属性的类文档包含在模式的<annotation>元素中。
    要禁用此功能,请将IncludeDocumentation属性指定为0。

注意:必须在调用AddSchemaType()方法之前设置这些属性。

  1. 调用实例的AddSchemaType()方法。
method AddSchemaType(class As %String, 
                     top As %String  = "", 
                     format As %String, 
                     summary As %Boolean  = 0, 
                     input As %Boolean  = 0, 
                     refOnly As %Boolean  = 0) as %Status
  • class是支持xml的类的完整包名和类名。
  • top 是可选的;
    如果指定,它将覆盖该类的类型名。
  • format指定此类型的格式。
    它必须是"literal"(文字格式,默认),"encoded"(用于SOAP编码),"encoded12"(用于SOAP 1.2编码),或"element"
    “element”与元素位于顶层的文字格式相同。
  • summary,如果为true,将导致InterSystems IRIS启用xml的类的XMLSUMMARY参数。
    如果指定了此参数,则模式将只包含该参数列出的属性。
  • input,如果为true,将导致InterSystems IRIS获取输入模式,而不是输出模式。
    在大多数情况下,输入模式和输出模式是相同的;
    如果为类的属性指定XMLIO属性参数,则它们是不同的。
  • refOnly如果为true,将导致InterSystems IRIS仅为引用的类型生成模式,而不是为给定的类和所有引用的类型生成模式。

这个方法返回一个应该被检查的状态。

  1. 根据需要重复前面的步骤。
  2. 如果要定义导入模式的位置,可以调用DefineLocation()方法。
method DefineLocation(namespace As %String, location As %String)

namespace 是一个或多个引用类使用的名称空间,位置是对应模式(XSD文件)的URL或路径和文件名。

可以重复调用此方法来为多个导入的模式添加位置。

如果不使用这个方法,模式会包含一个<import>指令,但是不会给出模式的位置。

  1. 要定义额外的<import>指令,可以调用DefineExtraImports()方法。
method DefineExtraImports(namespace As %String, ByRef imports)

namespace是<import>指令应该添加到的命名空间,imports是一个多维数组,形式如下:

Node Value
arrayname("namespace URI") 字符串,给出此名称空间的模式(XSD文件)的位置。

为架构生成输出

按照上一节所述创建%XML.Schema的实例后,请执行以下操作以生成输出:

  1. 调用实例的GetSchema()方法将架构作为文档对象模型(DOM)的节点返回。

此方法只有一个参数:模式的目标命名空间的URI。该方法返回%XML.Node的一个实例,该实例在“将XML文档表示为DOM”一章中介绍。

如果模式没有命名空间,请使用“”作为GetSchema()的参数。

  1. 可以选择修改此DOM。
  2. 要生成架构,请执行以下操作:

a. 创建%XML.Write的实例,并可选择设置属性(如缩进)。

b. 可以选择调用编写器的AddNamespace()方法和其他方法,将名称空间声明添加到<schema> 元素。

因为架构可能引用简单的XSD类型,所以调用AddSchemaNamespace()来添加XML模式命名空间很有用。

c. 使用架构作为参数,调用编写器的DocumentNode()Tree()方法。

示例

简单的示例

第一个示例显示了基本步骤:

    Set schemawriter=##class(%XML.Schema).%New()
    
    //添加类和包(例如)
    Set status=schemawriter.AddSchemaType("Facets.Test")
    
    //通过其URI(在本例中为NULL)检索架构
    Set schema=schemawriter.GetSchema("")
    
    //create writer
    Set writer=##class(%XML.Writer).%New()
    Set writer.Indent=1
    
    //use writer
    Do writer.DocumentNode(schema)

更复杂的架构示例

Class SchemaWriter.Person Extends (%Persistent, %XML.Adaptor)
{

Parameter NAMESPACE = "http://www.myapp.com";

Property Name As %Name;

Property DOB As %Date(FORMAT = 5);

Property PatientID as %String;

Property HomeAddress as Address;

Property OtherAddress as AddressOtherNS ;
}

Address类定义在相同的XML名称空间(“http://www.myapp.com”)中,而OtherAddress类定义在不同的XML名称空间(“http://www.other.com”)中。

Company类也被定义在XML名称空间“http://www.myapp.com”中。
其定义如下:

Class SchemaWriter.Company Extends (%Persistent, %XML.Adaptor)
{

Parameter NAMESPACE = "http://www.myapp.com";

Property Name As %String;

Property CompanyID As %String;

Property HomeOffice As Address;

}

注意,不存在连接PersonCompany类的属性关系。

要为命名空间"http://www.myapp.com"生成模式,我们可以使用以下方法:

ClassMethod Demo()
{
    Set schema=##class(%XML.Schema).%New()
    Set schema.DefaultNamespace="http://www.myapp.com"
    Set status=schema.AddSchemaType("SchemaWriter.Person")
    Set status=schema.AddSchemaType("SchemaWriter.Company")
    Do schema.DefineLocation("http://www.other.com","c:/other-schema.xsd")

    Set schema=schema.GetSchema("http://www.myapp.com")

    //create writer
    Set writer=##class(%XML.Writer).%New()
    Set writer.Indent=1
    
    Do writer.AddSchemaNamespace()
    Do writer.AddNamespace("http://www.myapp.com")
    Do writer.AddNamespace("http://www.other.com")
    
    Set status=writer.DocumentNode(schema)
    If $$$ISERR(status) {Do $system.OBJ.DisplayError() Quit }
 
}

输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
xmlns:s="http://www.w3.org/2001/XMLSchema" 
xmlns:s01="http://www.myapp.com" 
xmlns:s02="http://www.other.com" 
elementFormDefault="qualified" 
targetNamespace="http://www.myapp.com">
  <import namespace="http://www.other.com" schemaLocation="c:/other-schema.xsd"/>
  <complexType name="Person">
    <sequence>
      <element minOccurs="0" name="Name" type="s:string"/>
      <element minOccurs="0" name="DOB" type="s:date"/>
      <element minOccurs="0" name="PatientID" type="s:string"/>
      <element minOccurs="0" name="HomeAddress" type="s01:Address"/>
      <element minOccurs="0" name="OtherAddress" type="s02:AddressOtherNS"/>
    </sequence>
  </complexType>
  <complexType name="Address">
    <sequence>
      <element minOccurs="0" name="State">
        <simpleType>
          <restriction base="s:string">
            <maxLength value="2"/>
          </restriction>
        </simpleType>
      </element>
      <element minOccurs="0" name="Zip">
        <simpleType>
          <restriction base="s:string">
            <maxLength value="10"/>
          </restriction>
        </simpleType>
      </element>
    </sequence>
  </complexType>
  <complexType name="Company">
    <sequence>
      <element minOccurs="0" name="Name" type="s:string"/>
      <element minOccurs="0" name="CompanyID" type="s:string"/>
      <element minOccurs="0" name="HomeOffice" type="s01:Address"/>
    </sequence>
  </complexType>
</schema>

请注意以下几点:

  • 模式包括Person及其所有引用的类的类型,以及Company及其所有引用的类的类型。
  • <import>指令导入了OtherAddress类使用的命名空间;
    因为我们使用了DefineLocation(),所以这个指令还指示了相应模式的位置。
  • 因为我们在调用DocumentNode()之前使用了AddSchemaNamespace()AddNamespace(),所以<schema>元素包含了名称空间声明,它为这些名称空间定义了前缀。
  • 如果我们没有使用AddSchemaNamespace()AddNamespace()<schema>将不会包含这些名称空间声明,模式将会如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
elementFormDefault="qualified"
targetNamespace="http://www.myapp.com">
  <import namespace="http://www.other.com" schemaLocation="c:/other-schema.xsd"/>
  <complexType name="Person">
    <sequence>
      <element minOccurs="0" name="Name" type="s01:string" xmlns:s01="http://www.w3.org/2001/XMLSchema"/>
      <element minOccurs="0" name="DOB" type="s02:date" xmlns:s02="http://www.w3.org/2001/XMLSchema"/>
      <element minOccurs="0" name="PatientID" type="s03:string" xmlns:s03="http://www.w3.org/2001/XMLSchema"/>
      <element minOccurs="0" name="HomeAddress" type="s04:Address" xmlns:s04="http://www.myapp.com"/>
      <element minOccurs="0" name="OtherAddress" type="s05:AddressOtherNS" xmlns:s05="http://www.other.com"/>
    </sequence>
  </complexType>
  <complexType name="Address">
    <sequence>
      <element minOccurs="0" name="State">
        <simpleType>
          <restriction base="s06:string" xmlns:s06="http://www.w3.org/2001/XMLSchema">
...
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容