Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

XML ドキュメントの DOM 表現

%XML.DocumentOpens in a new tab クラスと %XML.NodeOpens in a new tab クラスを使用して、任意の XML ドキュメントを DOM (ドキュメント・オブジェクト・モデル) として表現できます。その後、このオブジェクトをナビゲートして変更できます。新しい DOM を作成してオブジェクトに追加することもできます。以下の項目について説明します。

Note:

使用する任意の XML ドキュメントの XML 宣言にはそのドキュメントの文字エンコードを明記する必要があり、明記しておけば、ドキュメントは宣言どおりにエンコードされるようになります。文字エンコードが宣言されていない場合は、このドキュメント内の前述の “入出力の文字エンコード” で説明されている既定値が使用されます。これらの既定値が正しくない場合は、XML 宣言を修正して、実際に使用されている文字セットを指定するようにします。

DOM として XML ドキュメントを開く

既存の XML ドキュメントを DOM として使用するために開くには、以下の手順を実行します。

  1. %XML.ReaderOpens in a new tab クラスのインスタンスを作成します。

  2. 必要に応じて、このインスタンスの Format プロパティを指定して、インポートするファイルの形式を指定します。

    既定では、XML ファイルはリテラル形式と想定されます。ファイルが SOAP でエンコードされた形式の場合は、そのように明記して、ファイルを正しく読み取れるようにする必要があります。

    Caché オブジェクトへの XML のインポート” の章の “リーダ・プロパティ” を参照してください。

    Correlate()Next() を使用していない場合、このプロパティには何の効果もなくなります。

  3. ソースを開きます。そのためには、%XML.ReaderOpens in a new tab の次のメソッドのいずれかを使用します。

    • OpenFile() — ファイルを開きます。

    • OpenStream() — ストリームを開きます。

    • OpenString() — 文字列を開きます。

    • OpenURL() — URL を開きます。

    いずれの場合も、オプションでメソッドに 2 番目の引数を指定して、Format プロパティの値をオーバーライドすることができます。

  4. DOM である Document プロパティにアクセスします。このプロパティは %XML.DocumentOpens in a new tab のインスタンスであり、ドキュメント全体についての情報を見つけるのに使用できるメソッドを提供します。例えば、CountNamespace() は DOM で使用されるネームスペースの総数を返します。

または、XML ドキュメントを格納したストリームがある場合は、%XML.DocumentOpens in a new tabGetDocumentFromStream() メソッドを呼び出します。これにより %XML.DocumentOpens in a new tab のインスタンスが返されます。

例 1 : ファイルの DOM への変換

例えば、以下のメソッドで XML ファイルを読み取り、そのドキュメントを表す %XML.DocumentOpens in a new tab のインスタンスを返します。

ClassMethod GetXMLDocFromFile(file) As %XML.Document
{
    set reader=##class(%XML.Reader).%New()

    set status=reader.OpenFile(file)
    if $$$ISERR(status) {do $System.Status.DisplayError(status) quit $$$NULLOREF}

    set document=reader.Document
    quit document
}

例 2 : オブジェクトの DOM への変換

以下のメソッドで OREF を受け入れ、そのオブジェクトを表す %XML.DocumentOpens in a new tab のインスタンスを返します。このメソッドでは、OREF は XML 対応のクラスのインスタンスと想定されます。

ClassMethod GetXMLDoc(object) As %XML.Document
{
    //make sure this is an instance of an XML-enabled class
    if '$IsObject(object){
        write "Argument is not an object"
        quit $$$NULLOREF
        }
    set classname=$CLASSNAME(object)
    set isxml=$zobjclassmethod(classname,"%Extends","%XML.Adaptor")
    if 'isxml {
        write "Argument is not an instance of an XML-enabled class"
        quit $$$NULLOREF
        }
    
    //step 1 - write object as XML to a stream
    set writer=##class(%XML.Writer).%New()
    set stream=##class(%GlobalCharacterStream).%New()
    set status=writer.OutputToStream(stream)
    if $$$ISERR(status) {do $System.Status.DisplayError(status) quit $$$NULLOREF}
    set status=writer.RootObject(object)
    if $$$ISERR(status) {do $System.Status.DisplayError(status) quit $$$NULLOREF}

    //step 2 - extract the %XML.Document from the stream
    set status=##class(%XML.Document).GetDocumentFromStream(stream,.document)
    if $$$ISERR(status) {do $System.Status.DisplayError(status) quit $$$NULLOREF}

   quit document
}

DOM のネームスペースの取得

Caché で XML ドキュメントを読み取り、DOM を作成するとき、ドキュメント内で使用されるすべてのネームスペースが識別され、それぞれにインデックス番号が割り当てられます。

%XML.DocumentOpens in a new tab クラスのインスタンスは、ドキュメント内のネームスペースについての情報を見つけるために使用できる以下のメソッドを提供します。

CountNamespace()

ドキュメント内のネームスペースの数を返します。

FindNamespace()

指定されたネームスペースに対応するインデックスを返します。

GetNamespace()

指定されたインデックスの XML ネームスペース URI を返します。

以下の例のメソッドは、ドキュメント内で使用されているネームスペースを示すレポートを表示します。

ClassMethod ShowNamespaces(doc As %XML.Document)
{
    Set count=doc.CountNamespace()
    Write !, "Number of namespaces in document: "_count
    For i=1:1:count { 
        Write !, "Namespace "_i_" is "_doc.GetNamespace(i)
}

}

この章で後述する “現在のノードについての情報の取得” も参照してください。

DOM のノードのナビゲート

ドキュメントのノードにアクセスするには、以下の 2 つの手法を使用できます。

  • %XML.DocumentOpens in a new tab のインスタンスの GetNode() メソッドを使用します。このメソッドは整数を受け入れます。この整数はノード番号を示すもので、1 から始まっています。

  • %XML.DocumentOpens in a new tab のインスタンスの GetDocumentElement() メソッドを呼び出します。

    このメソッドは、%XML.NodeOpens in a new tab のインスタンスを返します。これにより、ルート・ノードについての情報にアクセスし、他のノードに移動するのに使用するプロパティとメソッドが提供されます。以下のサブセクションには、%XML.NodeOpens in a new tab の操作に関する詳細が記述されています。

子ノードまたは兄弟ノードへの移動

子ノードまたは兄弟ノードに移動するには、%XML.NodeOpens in a new tab のインスタンスの以下のメソッドを使用します。

  • MoveToFirstChild()

  • MoveToLastChild()

  • MoveToNextSibling()

  • MoveToPreviousSibling()

これらの各メソッドは、(メソッド名で示されるように) 別のノードへの移動を試みます。移動が可能な場合、メソッドは True を返します。可能でない場合、メソッドは False を返し、フォーカスはメソッドが呼び出される前と同じ状態です。

これらの各メソッドには、オプションの引数 skipWhitespace があります。この引数が True の場合、メソッドは空白をすべて無視します。skipWhitespace の既定値は False です。

親ノードへの移動

現在のノードの親ノードに移動するには、%XML.NodeOpens in a new tab のインスタンスの MoveToParent() メソッドを使用します。

このメソッドはオプションの引数 restrictDocumentNode をとります。この引数が True の場合、メソッドはドキュメント・ノード (ルート) に移動しません。restrictDocumentNode の既定値は False です。

特定のノードへの移動

特定のノードに移動するために、%XML.NodeOpens in a new tab のインスタンスの NodeId プロパティを設定できます。以下はその例です。

   set saveNode = node.NodeId
   //..... lots of processing
   //... 
   // restore position
   set node.NodeId=saveNode

id 属性の使用

場合によっては、XML ドキュメントには id という名前の属性が含まれることがあります。これはドキュメント内の異なるノードを識別するために使用されます。以下はその例です。

<?xml version="1.0"?>
<team>
<member id="alpha">Jack O'Neill</member>
<member id="beta">Samantha Carter</member>
<member id="gamma">Daniel Jackson</member>
</team>

この例のようにドキュメントが id という属性を使用している場合、この属性を使用してそのノードに移動できます。このためには、そのノードの位置にある %XML.NodeOpens in a new tab のインスタンスを返す、ドキュメントの GetNodeById() メソッドを使用します。(他のほとんどの検索メソッドとは異なり、このメソッドは %XML.NodeOpens in a new tab ではなく %XML.DocumentOpens in a new tab から利用できることに注意してください。)

DOM ノード・タイプ

%XML.DocumentOpens in a new tab クラスと %XML.NodeOpens in a new tab クラスは、以下の DOM ノード・タイプを認識します。

  • 要素 ($$$xmlELEMENTNODE)

    これらのマクロは、%xml.DOM.inc インクルード・ファイルで定義します。

  • テキスト ($$$xmlTEXTNODE)

  • 空白 ($$$xmlWHITESPACENODE)

その他のタイプの DOM ノードは無視されます。

以下の XML ドキュメントについて考えてみます。

<?xml version="1.0"?>
<team>
<member id="alpha">Jack O'Neill</member>
<member id="beta">Samantha Carter</member>
<member id="gamma">Daniel Jackson</member>
</team>

DOM として表示する際、このドキュメントには以下のノードが含まれます。

ドキュメント・ノードの例
NodeID NodeType LocalName メモ
0,29 $$$xmlELEMENTNODE team  
1,29 $$$xmlWHITESPACENODE   このノードは、<team> ノードの子です。
1,23 $$$xmlELEMENTNODE member このノードは、<team> ノードの子です。
2,45 $$$xmlTEXTNODE Jack O'Neill このノードは、最初の <member> ノードの子です。
1,37 $$$xmlWHITESPACENODE   このノードは、<team> ノードの子です。
1,41 $$$xmlELEMENTNODE member このノードは、<team> ノードの子です。
3,45 $$$xmlTEXTNODE Samantha Carter このノードは、2 番目の <member> ノードの子です。
1,45 $$$xmlWHITESPACENODE   このノードは、<team> ノードの子です。
1,49 $$$xmlELEMENTNODE member このノードは、<team> ノードの子です。
4,45 $$$xmlTEXTNODE Daniel Jackson このノードは、3 番目の <member> ノードの子です。
1,53 $$$xmlWHITESPACENODE   このノードは、<team> ノードの子です。

ノード・タイプやローカル名などの詳細へのアクセスについては、次のセクションを参照してください。

現在のノードについての情報の取得

%XML.NodeOpens in a new tab の以下の文字列プロパティは、現在のノードについての情報を提供します。いずれの場合にも、現在のノードがないとエラーがスローされます。

LocalName

現在の要素ノードのローカル名。別のタイプのノードでこのプロパティにアクセスしようとすると、エラーがスローされます。

Namespace

現在の要素ノードのネームスペース URI。別のタイプのノードでこのプロパティにアクセスしようとすると、エラーがスローされます。

NamespaceIndex

現在の要素ノードのネームスペースのインデックス。

Caché で XML ドキュメントを読み取り、DOM を作成するとき、ドキュメント内で使用されるすべてのネームスペースが識別され、それぞれにインデックス番号が割り当てられます。

別のタイプのノードでこのプロパティにアクセスしようとすると、エラーがスローされます。

Nil

この要素ノードに対して xsi:nil または xsi:null が True または 1 の場合は True になります。それ以外の場合、このプロパティは False になります。

NodeData

文字ノードの値。

NodeId

現在のノードの ID。別のノードに移動するために、このプロパティを設定できます。

NodeType

前のセクションで説明している、現在のノードのタイプ。

QName

要素ノードの Qname。接頭語がドキュメントで有効な場合に、XML としての出力のみに使用されます。

以下のメソッドは、現在のノードについての追加情報を提供します。

GetText()
method GetText(ByRef text) as %Boolean

要素ノードのテキスト・コンテンツを取得します。テキストが返される場合、このメソッドは True を返します。この場合、実際のテキストは参照渡しの最初の引数に追加されます。

HasChildNodes()
method HasChildNodes(skipWhitespace As %Boolean = 0) as %Boolean

現在のノードに子ノードがある場合に True を返します。それ以外の場合は False を返します。

GetNumberAttributes()
method GetNumberAttributes() as %Integer

現在の要素の属性の番号を返します。属性については、この章の後半で詳細に説明しています。

以下の例のメソッドは、現在のノードについての情報を提供するレポートを記述します。

ClassMethod ShowNode(node as %XML.Node) 
{
    Write !,"LocalName="_node.LocalName
    If node.NodeType=$$$xmlELEMENTNODE  {
        Write !,"Namespace="_node.Namespace
    }
    If node.NodeType=$$$xmlELEMENTNODE {
        Write !,"NamespaceIndex="_node.NamespaceIndex
     }
    Write !,"Nil="_node.Nil
    Write !,"NodeData="_node.NodeData
    Write !,"NodeId="_node.NodeId
    Write !,"NodeType="_node.NodeType
    Write !,"QName="_node.QName
    Write !,"HasChildNodes returns "_node.HasChildNodes()
    Write !,"GetNumberAttributes returns "_node.GetNumberAttributes()
    Set status=node.GetText(.text)
    If status {
        Write !, "Text of the node is "_text
        } else {
            Write !, "GetText does not return text"
        }
}

出力例は以下のようになります。

LocalName=staff
Namespace=
NamespaceIndex=
Nil=0
NodeData=staff
NodeId=1
NodeType=e
QName=staff
HasChildNodes returns 1
GetNumberAttributes returns 5
GetText does not return text

属性の検証のための基本的なメソッド

%XML.NodeOpens in a new tab の以下のメソッドを使用して、現在のノードの属性を検証できます。その他のメソッドについては、この章で後述する “属性の検証のためのその他のメソッド” も参照してください。

  • AttributeDefined() — 現在の要素が指定した名前の属性を持つ場合、ゼロ以外 (True) を返します。

  • FirstAttributeName() — 現在の要素の最初の属性の属性名を返します。

  • GetAttributeValue() — 指定した属性の値を返します。要素に属性がない場合、メソッドは Null を返します。

  • GetNumberAttributes() — 現在の要素の属性の番号を返します。

  • LastAttributeName() — 現在の要素の最後の属性の属性名を返します。

  • NextAttributeName() — 属性名を指定すると、指定した属性が有効かどうかにかかわらず、このメソッドは照合順の次の属性の名前を返します。

  • PreviousAttributeName() — 属性名を指定すると、指定した属性が有効かどうかにかかわらず、このメソッドは照合順の前の属性の名前を返します。

以下の例は、指定したノードの属性を参照し、簡単なレポートを記述します。

ClassMethod ShowAttributes(node as %XML.Node) 
{
    Set count=node.GetNumberAttributes()
    Write !, "Number of attributes: ", count
    Set first=node.FirstAttributeName()
    Write !, "First attribute is: ", first
    Write !, "   Its value is: ",node.GetAttributeValue(first)
    Set next=node.NextAttributeName(first)

    For i=1:1:count-2 {
        Write !, "Next attribute is: ", next
        Write !, "   Its value is: ",node.GetAttributeValue(next)
        Set next=node.NextAttributeName(next)
        }
    Set last=node.LastAttributeName()
    Write !, "Last attribute is: ", last
    Write !, "   Its value is: ",node.GetAttributeValue(last)
}

以下の XML ドキュメントの例について考えてみます。

<?xml version="1.0"?>
<staff attr1="first" attr2="second" attr3="third" attr4="fourth" attr5="fifth">
  <doc>
    <name>David Marston</name>
  </doc>
</staff>

このドキュメントの最初のノードをメソッド例に渡すと、以下の出力が表示されます。

Number of attributes: 5
First attribute is: attr1
   Its value is: first
Next attribute is: attr2
   Its value is: second
Next attribute is: attr3
   Its value is: third
Next attribute is: attr4
   Its value is: fourth
Last attribute is: attr5
   Its value is: fifth

属性の検証のためのその他のメソッド

このセクションでは、属性の名前、値、ネームスペース、QName、および値ネームスペースを取得するのに使用できるメソッドについて説明します。これらのメソッドは以下のとおりに分類されます。

属性の検証のための基本的なメソッド” も参照してください。

属性名のみを使用するメソッド

属性についての情報を取得するには以下のメソッドを使用します。

GetAttribute()
method GetAttribute(attributeName As %String, 
                    ByRef namespace As %String, 
                    ByRef value As %String, 
                    ByRef valueNamespace As %String)

指定した属性のデータを返します。このメソッドは、参照により以下の値を返します。

  • namespace は、属性の QName からのネームスペース URI です。

  • value は属性値です。

  • valueNamespace は、その値が属するネームスペース URI です。例えば、以下の属性を考えてみます。

    xsi:type="s:string"
    

    この属性の値は string であり、この値は、別の場所で宣言され、接頭語を s とするネームスペースの中にあります。このドキュメントの既述部分に、以下のネームスペース宣言があったとします。

    xmlns:s="http://www.w3.org/2001/XMLSchema" 
    

    この場合、valueNamespace"http://www.w3.org/2001/XMLSchema" となります。

GetAttributeNamespace()
method GetAttributeNamespace(attributeName As %String) as %String

現在の要素の attributeName という名前の属性の QName から、ネームスペース URI を返します。

GetAttributeQName()
method GetAttributeQName(attributeName As %String) as %String

指定した属性の QName を返します。

GetAttributeValue()
method GetAttributeValue(attributeName As %String) as %String

指定した属性の値を返します。

GetAttributeValueNamespace()
method GetAttributeValueNamespace(attributeName As %String) as %String

指定した属性の値のネームスペースを返します。

属性名とネームスペースを使用するメソッド

名前とネームスペースの両方を使用して属性についての情報を取得するには、以下のメソッドを使用します。

GetAttributeNS()
method GetAttributeNS(attributeName As %String, 
                      namespace As %String, 
                      ByRef value As %String, 
                      ByRef valueNamespace As %String)

指定した属性のデータを返します。attributeName および namespace で目的の属性を指定します。このメソッドは、参照により以下のデータを返します。

  • value は属性値です。

  • valueNamespace は、その値が属するネームスペース URI です。例えば、以下の属性を考えてみます。

    xsi:type="s:string"
    

    この属性の値は string であり、この値は、別の場所で宣言され、接頭語を s とするネームスペースの中にあります。このドキュメントの既述部分に、以下のネームスペース宣言があったとします。

    xmlns:s="http://www.w3.org/2001/XMLSchema" 
    

    この場合、valueNamespace"http://www.w3.org/2001/XMLSchema" となります。

GetAttributeQNameNS()
method GetAttributeQNameNS(attributeName As %String, 
                           namespace As %String)
                           as %String

指定した属性の QName を返します。attributeName および namespace で目的の属性を指定します。

GetAttributeValueNS()
method GetAttributeValueNS(attributeName As %String, 
                           namespace As %String) 
                           as %String

指定した属性の値を返します。attributeName および namespace で目的の属性を指定します。

GetAttributeValueNamespaceNS
method GetAttributeValueNamespaceNS(attributeName As %String, 
                                    namespace As %String) 
                                    as %String

指定した属性の値のネームスペースを返します。attributeName および namespace で目的の属性を指定します。

DOM の作成または編集

DOM を作成するか既存の DOM を変更するには、%XML.DocumentOpens in a new tab の以下のメソッドを使用します。

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

ルート要素のみから構成される %XML.DocumentOpens in a new tab の新しいインスタンスを返します。

AppendCharacter()
method AppendCharacter(text As %String)

新しい文字データ・ノードをこの要素ノードの子のリストに追加します。現在のノードのポインタは変更されません。このノードは追加された子の親のままです。

AppendChild()
method AppendChild(type As %String)

新しいノードをこのノードの子のリストに追加します。現在のノードのポインタは変更されません。このノードは追加された子の親のままです。

AppendElement()
method AppendElement(localName As %String, 
                     namespace As %String, 
                     text As %String)

新しい要素ノードをこのノードの子のリストに追加します。テキストの引数が指定されると、文字データが新しい要素の子として追加されます。現在のノードのポインタは変更されません。このノードは追加された子の親のままです。

AppendNode()
method AppendNode(sourceNode As %XML.Node) as %Status

このノードの子として、指定したノードのコピーを追加します。コピーするノードは、任意のドキュメントをコピー元にできます。現在のノードのポインタは変更されません。このノードは追加された子の親のままです。

AppendTree()
method AppendTree(sourceNode As %XML.Node) as %Status

このノードの子として、指定したノードの (すべての子を含む) コピーを追加します。コピーするツリーは任意のドキュメントをコピー元にできますが、ソース・ノードの下位ノードをこのノードにすることはできません。現在のノードのポインタは変更されません。このノードは追加された子の親のままです。

InsertNamespace()
method InsertNamespace(namespace As %String)

指定されたネームスペース URI をドキュメントに追加します。

InsertCharacter()
method InsertCharacter(text as %String, ByRef child As %String, Output sc As %Status) as %String

このノードの子として、新しい文字データ・ノードを挿入します。新しい文字データは、指定した子ノードの直前に挿入されます。child 引数は、子ノードのノード ID です。これは参照によって渡されるため、挿入後に更新される可能性があります。挿入されたノードの NodeId が返されます。現在のノードのポインタは変更されません。

InsertNode()
method InsertNode(sourceNode As %XML.Node, ByRef child As %String, Output sc As %Status) as %String

このノードの子として、指定したノードのコピーを挿入します。コピーするノードは、任意のドキュメントをコピー元にできます。新規ノードは、指定した子ノードの直前に挿入します。child 引数は、子ノードのノード ID です。これは参照によって渡されるため、挿入後に更新される可能性があります。挿入されたノードの NodeId が返されます。現在のノードのポインタは変更されません。

InsertTree()
method InsertTree(sourceNode As %XML.Node, ByRef child As %String, Output sc As %Status) as %String

このノードの子として、指定したノードの (その子を含む) コピーを挿入します。コピーするツリーは任意のドキュメントをコピー元にできますが、ソース・ノードの下位ノードをこのノードにすることはできません。新規ノードは、指定した子ノードの直前に挿入します。child 引数は、子ノードのノード ID です。これは参照によって渡されるため、挿入後に更新される可能性があります。挿入されたノードの NodeId が返されます。現在のノードのポインタは変更されません。

Remove()
method Remove()

現在のノードを削除し、その親を現在のノードにします。

RemoveAttribute()
method RemoveAttribute(attributeName As %String)

指定された属性を削除します。

RemoveAttributeNS()
method RemoveAttributeNS(attributeName As %String, 
                         namespace As %String)

指定した属性を削除します。attributeName および namespace で目的の属性を指定します。

ReplaceNode()
method ReplaceNode(sourceNode As %XML.Node) as %Status

ノードを、指定したノードのコピーで置き換えます。コピーするノードは、任意のドキュメントをコピー元にできます。現在のノードのポインタは変更されません。

ReplaceTree()
method ReplaceTree(sourceNode As %XML.Node) as %Status

ノードを、指定したノードの (そのすべての子を含む) コピーで置き換えます。コピーするツリーは任意のドキュメントをコピー元にできますが、ソース・ノードの下位ノードにすることはできません。現在のノードのポインタは変更されません。

SetAttribute()
method SetAttribute(attributeName As %String, 
                    namespace As %String = "", 
                    value As %String = "", 
                    valueNamespace As %String = "")

現在の要素の属性のデータを設定します。以下はその説明です。

  • attributeName は、属性の名前です。

  • namespace は、この要素の attributeName という名前の属性の QName からのネームスペース URI です。

  • value は属性値です。

  • 属性値が "prefix:value" の形式である場合、valueNamespace は接頭語に相当するネームスペース URI です。

DOM からの XML 出力の記述

DOM または DOM のノードをシリアル化し、XML 出力を生成することができます。このためには、%XML.WriterOpens in a new tab の以下のメソッドを使用します。

Document()
method Document(document As %XML.Document) as %Status

%XML.DocumentOpens in a new tab のインスタンスを指定する場合、このメソッドは現在指定されている出力先にドキュメントを記述します。

DocumentNode()
method DocumentNode(document As %XML.Node) as %Status

%XML.NodeOpens in a new tab のインスタンスを指定する場合、このメソッドは現在指定されている出力先にノードを記述します。

Tree()
method Tree(node As %XML.Node) as %Status

%XML.NodeOpens in a new tab のインスタンスを指定する場合、このメソッドは現在指定されている出力先にノードとその下位ツリーを記述します。

出力先の指定と %XML.WriterOpens in a new tab のプロパティの設定の詳細は、“Caché オブジェクトからの XML 出力の記述” の章を参照してください。

FeedbackOpens in a new tab