本主题描述如何为任意数据或组合编写InterSystems IRIS对象的XML输出。
另请参阅从DOM编写XML输出。
7.1 概述
要编写XML,请执行以下操作:
-
如果需要特定对象的输出,则该对象的类定义必须启用XML。除了少数例外,该对象引用的类还必须扩展
%XML.Adaptor
。 -
创建
%XML.Writer
的实例,然后调用该实例的方法。您的代码将指定XML输出的整体结构:字符编码、对象的显示顺序、是否包含处理指令等等。
以下终端会话显示了一个简单的示例,该示例引用了一个启用XML的示例类:
GXML>Set p=##class(GXML.Person).%OpenId(1)
GXML>Set w=##class(%XML.Writer).%New()
GXML>Set w.Indent=1
GXML>Set status=w.RootObject(p)
<?xml version="1.0" encoding="UTF-8"?>
<Person GroupID="R9685">
<Name>Zimmerman,Jeff R.</Name>
<DOB>1961-10-03</DOB>
<Address>
<City>Islip</City>
<Zip>15020</Zip>
</Address>
<Doctors>
<Doctor>
<Name>Sorenson,Chad A.</Name>
</Doctor>
<Doctor>
<Name>Sorenson,Chad A.</Name>
</Doctor>
<Doctor>
<Name>Uberoth,Roger C.</Name>
</Doctor>
</Doctors>
</Person>
7.2 编写XML:详细信息
本节讨论以下项目:
- 代码的总体结构
- 错误检查
- 插入注释
- 一个基本的例子
7.2.1 总体结构
您的代码应该按以下顺序执行部分或全部操作:
-
如果您使用的对象可能无效,请调用该对象的
%ValidateObject()
方法并检查返回的状态。如果对象无效,那么XML也将无效。%XML.Writer
在导出对象之前不会验证对象。这意味着,如果您刚刚创建了一个对象,但尚未验证它,则该对象(因此XML)可能无效(例如,因为缺少所需的属性)。 -
创建
%XML.Writer
实例,并可以选择设置其属性。特别是,您可能需要设置以下属性:
- Indent — 控制输出是在缩进和换行中生成(如果Indent等于1),还是作为一条长行生成(如果Indent等于0)。后者是默认值。请参阅缩进选项的详细信息。
- IndentChars — 指定用于缩进的字符。默认值是由两个空格组成的字符串。如果缩进为0,则此属性无效。
- Charset — 指定要使用的字符集。请参见指定输出的字符集。
为了便于阅读,本文档中的示例使用了等于1的缩进。
另请参阅影响Prolog的属性和Writer的其他属性部分。
-
指定输出目标。
默认情况下,输出被写入当前设备。要指定输出目的地,请在开始编写文档之前调用以下方法之一:
- OutputToDevice() — 将输出指向当前设备。
- OutputToFile() — 将输出指向指定的文件。可以指定绝对路径或相对路径。请注意,目录路径必须已经存在。
- OutputToString() — 将输出指向字符串。稍后您可以使用另一种方法来检索此字符串。
- OutputToStream() — 将输出指向指定的流。
-
启动文档。您可以使用
StartDocument()
方法。请注意,如果您尚未通过StartDocument()
启动文档,则以下方法会隐式启动文档:Write()
、WriteDocType()
、RootElement()
、WriteComment()
和WriteProcessingInstruction()
。 -
可以选择编写文档的序言。您可以使用以下方法:
- WriteDocType() — 写入DOCTYPE声明。有关详细信息,请参见生成文档类型声明。
- WriteProcessingInstruction() — 写入处理指令。有关详细信息,请参阅编写处理说明。
-
(可选)指定默认命名空间。编写器将其用于没有定义的XML命名空间的类。请参见指定默认命名空间。
可以选择向根元素添加命名空间声明。为此,可以在启动根元素之前调用几个实用程序方法。请参见添加命名空间声明。
-
启动文档的根元素。细节取决于该文档的根元素是否对应于InterSystems IRIS对象。有两种可能性:
-
根元素可以直接对应于InterSystems IRIS对象。如果要为单个对象生成输出,则通常会出现这种情况。
在这种情况下,您使用
RootObject()
方法,该方法将指定的启用XML的对象作为根元素写入。 -
根元素可能只是一组元素的包装器,而这些元素是InterSystems IRIS对象。
在这种情况下,您使用
RootElement()
方法,该方法使用您指定的名称插入根级别的元素。
另请参阅编写根元素。
-
-
如果使用
RootElement()
方法,则调用方法为根元素内的一个或多个元素生成输出。您可以使用您选择的任何顺序或逻辑在根元素中写入任何元素。有几种方法可以编写单个元素,并且可以将这些技术结合起来:- 您可以使用
Object()
方法,该方法编写一个启用XML的对象。您可以指定此元素的名称,也可以使用由对象定义的默认名称。 - 您可以使用
Element()
方法,该方法使用您提供的名称为元素编写开始标记。然后,您可以使用WriteAttribute()
、WriteChars()
、WriteCData()
等方法来编写内容、属性和子元素。子元素可以是另一个element()
,也可以是Object()
。您可以使用EndElement()
方法来指示元素的结束。 - 您可以使用
%XML.Element
并手动构造一个元素。
有关详细信息,请参见手动构造元素。
- 您可以使用
-
如果您使用的是
RootElement()
方法,请调用EndRootElements()
方法。此方法关闭文档的根元素,并根据需要减少缩进(如果有)。 -
如果使用
StartDocument()
启动文档,请调用EndDocument()
方法关闭文档。 -
如果将输出定向到一个字符串,请使用
GetXMLString()
方法来检索该字符串。
还有许多其他可能的组织,但请注意,某些方法只能在某些上下文中调用。具体地说,一旦启动一个文档,在结束第一个文档之前,就无法启动另一个文档。如果尝试执行此操作,则writer方法将返回以下状态:
#6275: Cannot output a new XML document or change %XML.Writer properties
until the current document is completed.
StartDocument()
方法显式地启动文档。其他方法隐式启动文档:Write()
, WriteDocType()
, RootElement()
, WriteComment()
和WriteProcessingInstruction()
.
注:
这里描述的方法旨在使您能够向XML文档写入特定的单元,但在某些情况下,您可能需要更多的控制。
%XML.Writer
提供了一个额外的方法Write()
,您可以使用它将任意字符串写入输出中的任何位置。此外,还可以使用
Reset()
方法重新初始化writer属性。如果您已经生成了一个XML文档,并且希望在不创建新的编写器实例的情况下生成另一个文档,那么这将非常有用。
7.2.2 错误检查
%XML.Writer的大多数方法都返回一个状态。您应该在每个步骤后检查状态,并在适当的情况下退出。
7.2.3 插入注释行
您可以使用WriteComment()
方法插入注释行。您可以在文档中的任何位置使用此方法。如果尚未启动XML文档,则此方法将隐式启动文档。
7.2.4 实例
以下示例为给定的启用了XML的对象生成XML输出。
ClassMethod Write(obj) As %Status
{
set writer=##class(%XML.Writer).%New()
set writer.Indent=1
//these steps are not really needed because
//this is the default destination
set status=writer.OutputToDevice()
if $$$ISERR(status) {
do $System.Status.DisplayError(status)
quit $$$ERROR($$$GeneralError, "Output destination not valid")
}
set status=writer.RootObject(obj)
if $$$ISERR(status) {
do $System.Status.DisplayError(status)
quit $$$ERROR($$$GeneralError, "Error writing root object")
}
quit status
}
请注意,此示例使用OutputToDevice()
方法将输出定向到当前设备,这是默认的目的地。
假设我们执行这个方法如下:
set obj=##class(GXML.Person4).%OpenId(1)
do ##class(MyWriters.BasicWriter).Write(obj)
当然,输出取决于使用的类,但可能看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<Person4>
<Name>Tesla,Alexandra L.</Name>
<DOB>1983-11-16</DOB>
<GroupID>Y9910</GroupID>
<Address>
<City>Albany</City>
<Zip>24450</Zip>
</Address>
<Doctors>
<Doc>
<Name>Schulte,Frances T.</Name>
</Doc>
<Doc>
<Name>Smith,Albert M.</Name>
</Doc>
</Doctors>
</Person4>
7.2.5 缩进选项的详细信息
您可以使用编写器的“缩进”属性来获取包含额外换行符的输出,以提高可读性。这种格式没有正式的规范。本节介绍了%XML.Writer
使用的规则。如果缩进等于1:
- 任何只包含空白字符的元素都将转换为空元素。
- 每个元素都放置在自己的线上。
- 如果一个元素是前一个元素的子元素,则该元素相对于父元素缩进。缩进由IndentChars属性决定,该属性默认为两个空格。
7.3 指定字符集
要指定要在输出文档中使用的字符集,请设置编写器实例的Charset属性。选项包括“UTF-8”、“UTF-16”和InterSystems IRIS支持的其他字符集。
有关默认编码的信息,请参见输入和输出的字符编码。