文章 姚 鑫 · 七月 18, 2021 4m read

第七章 将文件内容复制到另外文件

示例

本例显示了一个使用本文前面介绍的几个%Library.File方法的样例类。

在示例类Demo.FileDemo中,ProcessFile()方法接受输入文件和输出文件,并调用SetUpInputFile()SetUpOutputFile()打开文件,一个用于读取,另一个用于写入。然后,它逐行读取输入文件,并调用ProcessLine()对每行的内容执行一个或多个替换,将每行的新内容写入输出文件。

/// 设置输入文件
/// 1. 创建文件对象
/// 2. 打开文件阅读
/// 3. 返回文件对象的句柄
ClassMethod SetUpInputFile(filename As %String) As %File
{
    Set fileObj = ##class(%File).%New(filename)
    Set status = fileObj.Open("RU")
    if $$$ISERR(status) { 
        do $system.Status.DisplayError(status) 
        quit $$$NULLOREF
    }
    quit fileObj
}

/// 设置输出文件
/// 1. 为文件创建目录结构
/// 2. 创建文件对象
/// 3.
0
0 219
文章 姚 鑫 · 七月 17, 2021 4m read

第六章 使用%File对象

如果想要操作文件本身,需要使用%Library.File%New()方法实例化%File对象。该类还提供了允许使用该文件的实例方法。

注意:本节提供了几个使用%File对象的示例,以供说明。

对于简单的文件读写,使用%Stream.FileCharacter和%Stream.FileBinary。因为它们提供了额外的功能,例如,以正确的模式自动打开文件。

创建%File对象的实例

要使用文件,需要使用%New()方法实例化表示该文件的%File对象。该文件可能已经存在,也可能不存在于磁盘上。

以下示例在默认目录中为文件export.xml实例化一个%File对象。

set fileObj = ##class(%File).%New("export.xml")

打开和关闭文件

实例化%File对象后,需要使用open()方法打开文件,以读取或写入该文件:

USER>set status = fileObj.Open()

USER>write status
1

使用Close()方法关闭文件:

USER>do fileObj.Close()

检查%File对象的属性

一旦实例化了文件,就可以直接检查文件的属性。

USER>write fileObj.Name
export.xml
USER>write fileObj.
0
0 241
文章 姚 鑫 · 七月 16, 2021 4m read

第五章 使用文件

使用文件

%Library.File类提供了几个类方法,允许对文件执行各种操作。

复制文件

若要复制文件,请使用CopyFile()方法,该方法返回一个布尔值来指示成功或失败。

此方法采用四个参数:

  1. from 从—指定源文件的名称。
  2. to至—指定目标文件的名称。
  3. pDeleteBeforeCopy —指定在执行复制之前是否删除目标文件(如果存在)。默认值为0。
  4. return 返回—输出参数。如果为负,则包含操作系统返回的错误代码,以防方法失败

下面的第一个示例将目录e:\temp中的文件old.txt复制到new.txt。第二个示例将相同的文件复制到默认目录中的new.txt

DHC-APP>write ##class(%File).CopyFile("e:\temp\old.txt", "e:\temp\new.txt", 0, .return)
1
DHC-APP>write ##class(%File).CopyFile("e:\temp\old.txt", "new.txt", 0, .return)
1

最后一个示例失败,Windows错误代码为2,或“找不到文件”

DHC-APP>write ##class(%File).CopyFile("foo.txt", "new.txt", 0, .
0
0 193
文章 姚 鑫 · 七月 15, 2021 4m read

第四章 使用目录

使用目录

%Library。File类提供了几个类方法,允许对目录执行各种操作。

创建目录

若要创建目录,请使用CreateDirectory()方法,该方法返回一个布尔值来指示成功或失败。这个方法需要两个参数。第一个参数是要创建的目录的名称。第二个参数是输出参数。如果为负,它包含操作系统返回的错误代码,以防方法失败。

如果e:\temp已经存在,以下命令将失败,并显示Windows系统错误代码183,这意味着“当文件已经存在时,无法创建该文件。”

DHC-APP>write ##class(%File).CreateDirectory("e:\temp", .return)
0
DHC-APP>w return
-183

如果e:\temp已经存在,但e:\temp\test不存在,则以下命令会失败,因为CreateDirectory()最多创建给定目录路径中的最后一个目录。所以返回的Windows系统错误代码是3,或者“系统找不到指定的路径。”

DHC-APP>write ##class(%File).CreateDirectory("e:\temp\test\this", .return)
0
DHC-APP>w return
-183

以下示例使用Windows系统代码0或“操作成功完成”成功完成

DHC-APP>write ##class(%File).
0
0 200
文章 姚 鑫 · 七月 14, 2021 6m read

第三章 处理文件和目录名

%Library.File类提供了几个可用于处理文件名和目录名的类方法。在大多数情况下,文件和目录不需要存在即可使用这些方法。

获取文件名和目录名

%Library.File类提供可用于获取部分文件名和目录名的类方法。

在给定完整路径名的情况下,使用GetDirectory()GetFilename()分别获取目录和短文件名。对于此方法,不允许使用部分目录名。

DHC-APP>set filename = "e:\temp\config.txt"
 
DHC-APP>write ##class(%File).GetDirectory(filename)
E:\temp\
DHC-APP>write ##class(%File).GetFilename(filename)
config.txt

在给定文件名的情况下,使用CanonicalFilename()从根目录获取完整路径:

DHC-APP>set filename = "cache.dat"
 
DHC-APP>write ##class(%File).CanonicalFilename(filename)
e:\dthealth\db\dthis\data\cache.dat
DHC-APP>write ##class(%File).CanonicalFilename("foo.
0
0 192
文章 姚 鑫 · 七月 13, 2021 6m read

第二章 使用文件和目录属性和属性

%Library.File类还提供了许多类方法,可以使用这些方法来获取有关文件和目录的信息,或者查看或设置它们的属性和属性。

检查文件和目录是否存在

要确定给定文件是否存在,请使用Existes()方法并指定文件名作为参数。例如:

DHC-APP>write ##class(%File).Exists("e:\temp\")
1

同样,要找出给定目录是否存在,请使用DirectoryExists()方法,并将该目录指定为参数。例如:

DHC-APP>write ##class(%File).DirectoryExists("e:\temp")
1

如前所述,这些方法在Unix上将文件或目录名视为区分大小写,但在Windows上不区分大小写。此外,如果指定部分文件名或目录名,则该方法引用的文件或目录相对于包含正在使用的命名空间的默认全局数据库的目录。例如:

DHC-APP>write ##class(%File).Exists("cache.dat")
1

查看和设置文件和目录权限

%Library.File类提供了许多类方法,可以使用这些方法查看或设置文件或目录的权限。

查看文件或目录是只读的还是可写的

给定文件或目录名,如果文件或目录是只读的,ReadOnly()方法返回1,否则返回0:

DHC-APP>write ##class(%File).
1
0 223
文章 姚 鑫 · 七月 12, 2021 5m read

第一章 查询目录和驱动器

%Library.File(简称%File)为处理文件和目录提供了广泛的API。本文将介绍该API的主要功能。有关属性、方法和查询的规范列表,请参见类参考。

注意:如果指定了部分文件名或目录名,这些方法中的大多数都引用的项相对于包含正在使用的命名空间的默认全局数据库的目录。该目录在本文中称为“默认目录”。这条规则的任何例外都在文章中注明。

此外,仅当基础操作系统将文件名和目录名视为区分大小写时,这些方法才会将文件名或目录名视为区分大小写。也就是说,文件或目录名在Unix上区分大小写,但在Windows上不区分大小写。

查询目录和驱动器

列出目录的内容

FileSet类查询列出目录的内容。此查询按顺序接受以下参数:

  1. directory — 指定要检查的目录的名称。
  2. wildcards 通配符 — 指定要匹配的文件名模式(如果有)。
  3. sortby 排序依据 — 指定如何对结果进行排序。使用以下值之一:
  • Name 名称—文件的名称(默认)
  • Type 类型—项目类型
  • DateCreated 创建日期—创建文件的日期和时间
  • DateModified 日期修改—文件上次修改的日期和时间
  • Size 大小—文件大小
  1. includedirs —指定如何处理给定目录中的目录。如果此参数为真(1),查询将返回任何文件之前的所有目录,并且目录名忽略通配符参数。
0
0 151
文章 姚 鑫 · 七月 9, 2021 6m read

第三十二章 XML基础知识概念

attribute

以下形式的名值对:

ID="QD5690"

属性位于元素中,如下所示,一个元素可以有任意数量的属性。

<Patient ID="QD5690">Cromley,Marcia N.</Patient>

CDATA区域

表示不应该验证的文本,如下所示:

<myelementname><![CDATA[ 
Non-validated data goes here.  
You can even have stray "<" or ">" symbols in it. 
]]></myelementname>

一个CDATA(字符数据)区段不能包含字符串]]>,因为这个字符串标志着区段的结束。 这也意味着CDATA区段不能嵌套。

注意,CDATA部分的内容必须符合为XML文档指定的编码,XML文档的其余部分也是如此。

comment

不是XML文档主数据的一部分的插入说明。 注释是这样的:

<!--Output for the class: GXML.PersonNS7-->

content model

对XML元素的可能内容的抽象描述。

0
0 227
文章 姚 鑫 · 七月 8, 2021 2m read

第三十一章 检查命名空间和类

%XML.Namespaces提供了两个类方法,可用于检查XML命名空间及其包含的类:

GetNextClass()

classmethod GetNextClass(namespace As %String, 
            class As %String) as %String

返回给定XML命名空间中给定类之后的下一个类(按字母顺序)。当没有更多的类时,此方法返回NULL

GetNextNamespace()

classmethod GetNextNamespace(namespace As %String) as %String

返回给定命名空间之后的下一个命名空间(按字母顺序)。当没有更多的命名空间时,此方法返回NULL

在这两种情况下,只考虑当前的InterSystems IRIS命名空间。此外,映射的类也会被忽略。

例如,以下方法列出当前InterSystems IRIS命名空间的XML命名空间及其类:

ClassMethod WriteNamespacesAndClasses()
{
  Set ns=""
  Set ns=##class(%XML.Namespaces).GetNextNamespace(ns)

  While ns '=""
  {
    Write !
0
0 158
文章 姚 鑫 · 七月 7, 2021 5m read

第三十章 从类生成XML架构

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

概述

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

从多个类构建架构

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

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

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

  1. 调用实例的AddSchemaType()方法。
0
0 191
文章 姚 鑫 · 七月 6, 2021 9m read

第二十九章 从XML架构生成类

Studio提供了一个向导,该向导读取XML模式(从文件或URL),并生成一组支持XML的类,这些类对应于模式中定义的类型。 所有的类都扩展%XML.Adaptor。 指定一个包来包含类,以及控制类定义细节的各种选项。

向导还可以作为类方法使用,也可以使用该类方法。 在内部,SOAP向导在读取WSDL文档并生成web客户端或web服务时使用此方法;

注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码,InterSystems IRIS将使用本书前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。

使用向导

要使用XML架构向导,请执行以下操作:

  1. 选择 Tools > Add-Ins > XML Schema Wizard.

image

  1. 在第一个屏幕上,指定要使用的XML模式。 做以下其中一项:
  • 对于模式文件Schema File,选择Browse 以选择XML模式文件。
  • 对于URL,指定模式的URL。

image

  1. 选择Next。

下一个屏幕显示模式,以便可以验证选择了正确的模式。 image

  1. 可选择以下选项:
  • 保留空类Keep Empty Classes,它指定是否保留没有属性的未使用的类。 如果选择此选项,则不会在向导结束时删除此类; 否则,将删除它们。
0
0 228
文章 姚 鑫 · 七月 5, 2021 7m read

[toc]

第二十八章 定制SAX解析器创建自定义内容处理程序

创建自定义内容处理程序

如果直接调用InterSystems IRIS SAX解析器,则可以根据自己的需要创建自定义内容处理程序。本节讨论以下主题:

  • Overview
  • 要在内容处理程序中自定义的方法的描述
  • %XML.SAX.Parser类中解析方法的参数列表摘要
  • 示例

创建自定义内容处理程序概述

要定制InterSystems IRIS SAX解析器导入和处理XML的方式,请创建并使用定制的SAX内容处理程序。具体地说,创建%XML.SAX.ContentHandler的子类。然后,在新类中,重写任何默认方法以执行所需的操作。在解析XML文档时使用新的内容处理程序作为参数;为此,需要使用%XML.SAX.Parser类的解析方法。

此操作如下图所示:

image

创建和使用自定义导入机制的过程如下:

  1. 创建扩展%XML.SAX.ContentHandler的类。
  2. 在该类中,包括希望覆盖的方法,并根据需要提供新定义。
  3. 在使用%XML.SAX.Parser的分析方法之一(即ParseFile()ParseStream()ParseString()ParseURL())编写读取XML文档的类方法。

调用分析方法时,请将自定义内容处理程序指定为参数。

SAX内容处理程序的可定制方法

%XML.SAX.

0
0 283
文章 姚 鑫 · 七月 4, 2021 4m read

第二十七章 定制SAX解析器的执行自定义实体解析

执行自定义实体解析

XML文档可能包含对外部DTD或其他实体的引用。默认情况下,InterSystems IRIS尝试查找这些实体的源文档并解析它们。要控制InterSystems IRIS解析外部实体的方式,请使用以下步骤:

  1. 定义实体解析程序类。

此类必须在扩展%XML.SAX.EntityResolver,并且必须实现 resolveEntity()方法,该方法具有以下签名:

method resolveEntity(publicID As %Library.String, systemID As %Library.String) as %Library.Integer

每当XML处理器找到对外部实体(如DTD)的引用时,就会调用该方法;这里的public ID和systemID是该实体的Public和系统标识符字符串。

该方法应获取实体或文档,将其作为流返回,然后在将流包装在%XML.SAX.StreamAdapter的实例中。此类提供了用于确定流特征的必要方法。

如果无法解析该实体,则该方法应返回$$$NULLOREF ,以向SAX解析器指示该实体无法解析)。

尽管方法签名指示返回值为%Library.Integer,但该方法应返回%XML.SAX.StreamAdapter的实例或该类的子类。

0
0 142
文章 姚 鑫 · 七月 3, 2021 7m read

第二十六章 定制 SAX解析器的使用方式

每当InterSystems IRIS读取XML文档时,它都会使用InterSystems IRIS SAX(Simple API For XML)解析器。本章介绍用于控制系统间IRIS SAX解析器的选项。

关于IRIS SAX解析器

每当InterSystems IRIS读取XML文档时,都会使用InterSystems IRIS SAX解析器。

它是一个事件驱动的XML解析器,读取XML文件,并在找到感兴趣的项(如XML元素的开始、DTD的开始等)时发出回调。

(更准确地说,解析器与内容处理程序协同工作,内容处理程序发出回调。只有在自定义SAX接口时,此区别才很重要,如本章后面的“创建自定义内容处理程序”中所述。)

解析器使用标准Xerces-C++库,该库符合XML1.0推荐标准和许多相关标准。

可用的解析器选项

可以通过以下方式控制SAX解析器的行为:

  • 可以设置标志来指定要执行的验证和处理类型。

请注意,解析器始终检查文档是否为格式良好的XML文档。

  • 可以指感兴趣的事件(即希望解析器查找的项目)。为此,需要指定一个掩码来指示感兴趣的事件。
  • 可以提供验证文档所依据的架构规范。
  • 可以使用特殊用途的实体解析器禁用实体解析。
  • 可以指定实体解析的超时期限。
  • 如果需要控制解析器如何查找文档中任何实体的定义,则可以指定更通用的自定义实体解析器。
0
0 232
文章 姚 鑫 · 七月 2, 2021 5m read

第二十五章 添加和使用XSLT扩展函数

自定义错误处理

当出现错误时,XSLT处理器(XalanSaxon)执行当前错误处理程序的error()方法,将消息作为参数发送到该方法。类似地,当发生致命错误或警告时,XSLT处理器会根据需要执行datalError()Warning()方法。

对于所有这三种方法,默认行为是将消息写入当前设备。

要自定义错误处理,请执行以下操作:

  • 对于XalanSaxon处理器,在创建%XML.XSLT.ErrorHandler的子类。在这个子类中,根据需要实现Error()FatealError()Warning()方法。

这些方法中的每一个都接受单个参数,即包含由XSLT处理器发送的消息的字符串。

这些方法不返回值。

  • 要在编译样式表时使用此错误处理程序,请创建子类的实例,并在编译样式表时在参数列表中使用它。
  • 若要在执行XSLT转换时使用此错误处理程序,请创建子类的实例,并在使用的Transform方法的参数列表中使用它。

指定样式表使用的参数

要指定样式表使用的参数,请执行以下操作:

  1. 创建%ArrayOfDataTypes的实例在。
  2. 调用此实例的SetAt()方法将参数及其值添加到此实例。对于SetAt(),将第一个参数指定为参数值,将第二个参数指定为参数名称。

根据需要添加任意多个参数。

0
0 173
文章 姚 鑫 · 七月 1, 2021 3m read

第二十四章 执行XSLT转换

执行XSLT转换

要执行XSLT转换,请执行以下操作:

  • 如果使用的是Xalan处理器(对于XSLT 1.0),请使用%XML.XSLT.Transformer的以下类方法之一:
    • TransformFile()——转换给定XSLT样式表的文件。
    • TransformFileWithCompiledXSL()——转换一个文件,给定一个已编译的XSLT样式表。
    • TransformStream()——转换给定XSLT样式表的流。
    • TransformStreamWithCompiledXSL()——转换一个流,给定一个已编译的XSLT样式表。
    • TransformStringWithCompiledXSL()——转换给定已编译XSLT样式表的字符串。
  • 如果使用Saxon处理器(用于XSLT 2.0),请使用%XML.XSLT2.Transformer的以下类方法之一:
    • TransformFile()——转换给定XSLT样式表的文件。
    • TransformFileWithCompiledXSL()——转换一个文件,给定一个已编译的XSLT样式表。
    • TransformStream()——转换给定XSLT样式表的流。
    • TransformStreamWithCompiledXSL()——转换一个流,给定一个已编译的XSLT样式表。

这些方法具有相似的签名。

0
0 164
文章 姚 鑫 · 六月 30, 2021 7m read

第二十三章 执行XSLT转换概述

XSLT(Extensible StyleSheet Language Transformations,可扩展样式表语言转换)是一种基于XML的语言,用于描述如何将给定的XML文档转换为另一个XML或其他“人类可读”的文档。可以使用%XML.XSLT%XML.XSLT2包中的类来执行XSLT 1.02.0转换。

注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码, IRIS将使用本书前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。

在IRIS中执行XSLT转换概述

IRIS提供两个XSLT处理器,每个处理器都有自己的API:

  • Xalan处理器支持XSLT 1.0XML.XSLT包为该处理器提供API。
  • Saxon处理器支持XSLT 2.0%XML.XSLT2程序包为该处理器提供API。

XML.XSLT2 API通过到XSLT 2.0网关的连接向Saxon发送请求。网关允许多个连接。这意味着,例如,可以将两个独立的 IRIS进程连接到网关,每个进程都有自己的一组编译样式表,同时发送转换请求。

使用Saxon处理器,编译的样式表和isc:Evaluate缓存是特定于连接的;必须管理自己的连接才能利用这两个特性。

0
0 312
文章 姚 鑫 · 六月 29, 2021 9m read

第二十二章 计算XPath表达式

XPath(XML路径语言)是一种基于XML的表达式语言,用于从XML文档获取数据。使用类中的%XML.XPATH.Document,可以轻松地计算XPath表达式(给定提供的任意XML文档)。

注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码,InterSystems IRIS将使用本书前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。

IRIS中XPath表达式求值概述

要使用InterSystems IRIS XML支持使用任意XML文档计算XPath表达式,请执行以下操作:

  1. 创建%XML.XPATH.Document的实例。为此,请使用以下类方法之一:CreateFromFile()CreateFromStream()CreateFromString()``。使用这些方法中的任何一种,都可以将输入XML文档指定为第一个参数,并接收%XML.XPATH.Document的一个实例作为输出参数。

这一步使用内置的XSLT处理器解析XML文档。

  1. 使用%XML.XPATH.Document实例的EvaluateExpression()方法。对于此方法,需要指定节点上下文和要计算的表达式。
0
0 220
文章 姚 鑫 · 六月 28, 2021 6m read

第二十一章 使用%XML.TextReader 导航文档

导航文档

要在文档中导航,请使用文本阅读器的以下方法:Read()ReadStartElement()MoveToAttributeIndex()MoveToAttributeName()MoveToElement()MoveToContent()Rewind()

导航到下一个节点

要移动到文档中的下一个节点,请使用read()方法。Read()方法返回TRUE值,直到没有更多节点可读为止(即,直到到达文档末尾)。前面的示例在如下所示的循环中使用了此方法:

 While (textreader.Read()) {

...

 }

导航到特定元素的第一个匹配项

可以移动到文档中特定元素的第一个匹配项。为此,请使用ReadStartElement()方法。除非找不到元素,否则此方法返回TRUE。如果未找到该元素,则该方法到达文件末尾。

ReadStartElement()方法有两个参数:元素的名称和命名空间URI(可选)。请注意,类中的%XML.TextReader不会对命名空间前缀进行任何处理。因此,ReadStartElement()方法将以下两个元素视为具有不同的名称:

<Person>Smith,Ellen W. xmlns="http://www.
0
0 154
文章 姚 鑫 · 六月 27, 2021 5m read

第二十章 使用%XML.TextReader 节点属性

节点属性

如前所述,类中的%XML.TextReader解析XML文档并创建一个text reader对象,该对象由一组与文档组件相对应的节点组成;节点类型在本章前面的“文档节点”中进行了描述。

当将焦点更改到其他节点时,text reader对象的属性将更新,以包含有关当前检查的节点的信息。本节介绍类中%XML.TextReader的所有属性。

AttributeCount

如果当前节点是元素或属性,则此属性指示元素的属性数。在给定元素中,第一个属性编号为1。对于任何其他类型的节点,此属性为0

Depth

指示文档中当前节点的深度。根元素位于深度1;根元素之外的项位于深度0。请注意,属性与其所属元素的深度相同。同样,错误或警告与导致错误或警告的项的深度相同。

EOF

如果读取器已到达源文档的末尾,则为true;否则为false。

HasAttributes

如果当前节点是一个元素,则如果该元素具有属性,则此属性为true(如果没有属性,则为false)。如果当前节点是属性,则此属性为true。对于任何其他类型的节点,此属性为False。

HasValue

如果当前节点是具有值的节点类型(即使该值为空),则为True。否则,此属性为false。

0
0 164
文章 姚 鑫 · 六月 26, 2021 6m read

第十九章 使用%XML.TextReader

%XML.TextReader类提供了一种简单、容易的方法来读取可能直接映射到InterSystems IRIS对象,也可能不直接映射到InterSystems IRIS对象的任意XML文档。具体地说,该类提供了导航格式良好的XML文档并查看其中信息(元素、属性、注释、名称空间URI等)的方法。该类还基于DTDXML架构提供完整的文档验证。但是,与%XML.Reader不同的是,%XML.TextReader不提供返回DOM的方法。如果需要DOM,请参阅前面的“将XML导入对象”一章。

注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码,InterSystems IRIS将使用前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。

创建文本阅读器Text Reader方法

要读取不一定与 IRIS对象类有任何关系的任意XML文档,可以调用%XML.TextReader类的方法,该类将打开文档并将其作为文本阅读器对象加载到临时存储中。文本阅读器对象包含一个可导航的节点树,每个节点都包含有关源文档的信息。然后,方法可以导航该文档并查找有关该文档的信息。对象的属性提供有关文档的信息,这些信息取决于在文档中的当前位置。

0
0 156
文章 姚 鑫 · 六月 25, 2021 10m read

第十八章 签署XML文档

本章介绍如何向XML文档添加数字签名。

关于数字签名文档

数字签名的XML文档包括一个或多个元素,每个元素都是数字签名。 每个元素对文档中的特定元素进行如下签名:

  • 每个签名元素都有一个ID属性,该属性等于某个唯一值。例如:
<Person xmlns="http://mynamespace" Id="123456789">
  • 一个元素包含一个元素,它指向该Id,如下所示:
<Reference URI="#123456789">

元素是由私钥签名的。此元素包括由签名机构签署的X.509证书。如果已签名文档的接收方信任此签名机构,则接收方可以验证证书,并使用包含的公钥验证签名。

注意: IRIS还支持一种变体,其中有签名的元素有一个名为ID的属性,而不是ID。

下面是一个示例,为了便于阅读,添加了空格:

<?xml version="1.0" encoding="UTF-8"?>
<Person xmlns="http://mynamespace" Id="123456789">
  <Name>Persephone MacMillan</Name>
  <DOB>1976-02-20</DOB>
  <s01:Signature xmlns="http://www.w3.
0
0 290
文章 姚 鑫 · 六月 24, 2021 6m read

第十七章 加密XML文档

本章介绍如何加密XML文档。

提示:发现在此命名空间中启用SOAP日志记录非常有用,这样就可以收到有关任何错误的更多信息。

关于加密的XML文档

加密的XML文档包括以下元素:

  • 元素,其中包含由随机生成的对称密钥加密的加密数据。(使用对称密钥加密比使用公钥加密更有效。)
  • 至少有一个元素。每个元素携带用于加密数据的对称密钥的加密副本;它还包含一个带有公钥的X.509证书。拥有匹配私钥的接收方可以解密对称密钥,然后解密元素。
  • (可选)其他明文元素。
<?xml version="1.0" encoding="utf-8"?>

<Container xmlns="http://www.w3.org/2001/04/xmlenc#">  
  <EncryptedKey> 
    <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"> 
      <DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.
0
0 339
文章 姚 鑫 · 六月 23, 2021 4m read

第十六章 创建或编辑DOM

创建或编辑DOM

要创建DOM或修改现有DOM,请使用%XML.Document的以下方法在:

CreateDocument()

classmethod CreateDocument(localName As %String, 
                           namespace As %String) 
                           as %XML.Document 

在仅包含根元素的返回%XML.Document新实例。

AppendCharacter()

method AppendCharacter(text As %String)

将新的字符数据节点追加到此元素节点的子节点列表中。当前节点指针不变;此节点仍然是追加的子节点的父节点。

AppendChild()

method AppendChild(type As %String)

将新节点追加到此节点的子节点列表中。当前节点指针不变;此节点仍然是追加的子节点的父节点。

0
0 145
文章 姚 鑫 · 六月 22, 2021 5m read

第十五章 XML检查属性

检查属性的基本方法

可以使用%XML.Node的以下方法。以检查当前节点的属性。

  • AttributeDefined() 如果当前元素具有具有给定名称的属性,则返回非零(TRUE)。
  • FirstAttributeName() 返回当前元素的第一个属性的属性名称。
  • GetAttributeValue() 返回给定属性的值。如果元素没有该属性,则该方法返回NULL。
  • GetNumberAttributes() 返回当前元素的属性数。
  • LastAttributeName() 返回当前元素的最后一个属性的属性名称。
  • NextAttributeName() 在给定属性名称的情况下,无论指定的属性是否有效,此方法都会按排序顺序返回下一个属性的名称。
  • PreviousAttributeName() 在给定属性名称的情况下,无论指定的属性是否有效,此方法都会按排序顺序返回上一个属性的名称。

下面的示例遍历给定节点中的属性并编写一个简单报表:


/// d ##class(Demo.XmlDemo).ShowAttributes("<?xml version='1.0'?
0
0 125
文章 姚 鑫 · 六月 21, 2021 3m read

第十四章 XML获取当前节点信息

DOM节点类型

%XML.Document%XML.Node类识别以下DOM节点类型:

  • Element ($$$xmlELEMENTNODE)

请注意,这些宏在%xml.DOM.inc包含文件中定义。

  • Text ($$$xmlTEXTNODE)

  • Whitespace ($$$xmlWHITESPACENODE).

其他类型的DOM节点被简单地忽略。

请以下XML文档:

<?xml version="1.0"?
0
0 175
文章 姚 鑫 · 六月 20, 2021 5m read

第十三章 将XML文档表示为DOM

%XML.Document类和%XML.Node类使可以将任意XML文档表示为DOM(文档对象模型)。然后,可以导航此对象并对其进行修改。还可以创建一个新的DOM并将其添加到其中。

注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码,InterSystems IRIS将使用本书前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。

将XML文档作为DOM打开

要打开现有XML文档以用作DOM,请执行以下操作:

  1. 创建%XML.Reader的实例。
  2. 也可以指定此实例的Format属性,以指定要导入的文件的格式。

默认情况下, IRIS假定XML文件为文字格式。如果文件是SOAP编码格式,则必须指明这一点,以便可以正确读取该文件。

除非使用Correlate()Next(),否则此属性无效。

  1. 请使用%XML.Reader的以下方法之一。
  • OpenFile() — 打开一个文件。
  • OpenStream() —打开一个流。
  • OpenString() — 打开字符串。
  • OpenURL() — 打开URL。

在每种情况下,都可以选择为该方法指定第二个参数,以重写Format属性的值。

  1. 访问Document属性,它是一个DOM。
0
0 165
文章 姚 鑫 · 六月 19, 2021 5m read

第十二章 XML其他示例

其他示例

Flexible Reader类

/// desc:灵活读取类
ClassMethod Read(mydir, myfile, class, element)
{
	set reader=##class(%XML.Reader).%New()
	if $extract(mydir,$length(mydir))'="/" {set mydir=mydir_"/"}
	set file=mydir_myfile
	set status=reader.OpenFile(file)
	if $$$ISERR(status) {do $System.Status.DisplayError(status)}

	do reader.Correlate(element,class)

	while reader.Next(.object,.status)
	{
		if $$$ISERR(status) {do $System.Status.DisplayError(status)}
		set status=object.%Save()
		if $$$ISERR(status) {do $System.Status.DisplayError(status)}
	}
}

请注意,当读入Person对象时,会自动读入其相应的Address对象。

0
0 232
文章 姚 鑫 · 六月 18, 2021 6m read

第十一章 重新定义读取器处理相关对象的方式

重新定义读取器处理相关对象的方式

%XML.Reader找到与启用了XML的类相关的XML元素时,读取器会调用该类的XMLNew()方法,后者又会在默认情况下调用%New()。也就是说,当读取器找到相关元素时,它会创建相关类的新对象。新对象由从XML文档读取的数据填充。

可以通过在启用XML的类中(或在自己的自定义XML适配器中)重新定义XMLNew()来自定义此行为。例如,此方法可以改为打开该类的现有实例。然后,现有实例接收从XML文档读取的数据。

以下示例显示如何修改XMLNew()以使用XML文档中的新数据更新现有实例。

在这两个示例中,为简单起见,我们假设XML文档中的一个节点包含一个ID,我们可以将该ID与类的范围中的ID进行比较。当然,我们可以用其他方式将XML文档与现有对象进行比较。

%XML.Reader调用XMLNew()

作为参考,%XML.Reader在两种情况下自动调用XMLNew()方法:

  • %XML.Reader在调用%XML.ReaderNext()方法调用XMLNew()。在将XML元素(在外部文档中)与启用了XML的类关联之后,%XML.Reader Next()方法从文档中获取下一个元素,调用XMLNew()创建相应对象的实例,然后将该元素导入到对象中。
  • 同样,%XML.
0
0 154