How to use %XML.Node
I have read here and tried to use the supplied examples to see what they do but keep on getting error please advice:
Method GetXMLDocFromFile(file = "C:test2.xml") 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
set reNo=##class(%XML.Node).%New()//check here
set reNo.Document=document//check here
do ..ShowNamespaces(document)
do ..ShowNode(reNo)//check here
quit document
}
Method 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)
}
}
//how to use the below method
Method 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"
}
}
the error I am getting is as follows:<UNDEFINED>zGetXMLDocFromFile+5^XMLToDyna.3 *reNo.If you check where I highlighted in red I have defined reNo so where am I going wrong
Use static classmethods, unless you need them to be instance methods.
I have changed it to class method and still same error
@Eduard Lebedyuk
I'd move
into a separate method:
Try to remove reNo altogether and get the root node from the xml document:
In GetDocumentElement method, you can see that for node to exist it needs 2 things:
When you created the node manually, you've done the first but not the second.
This was more a code correction exercise.
Honestly I wouldn't have done it that way at all. But using %XML.TextReader instead.
It was just to late in the evening to do a pretty solution.
The next auditor may do it.
BTW. for Attributes it'S %lev+1*3
As Eduard already pointed out there is just no need to use %XML.Node as %XML.Document inherits it already
I have elaborated your code also to cover Attributes and Chlidren in the document.
and added some readability features.
To some extend %XML.TextReader could have done the same.
No need to copy the code from browser the class + test data is attached. xmlreading.zip
{
ClassMethod GetXMLDocFromFile(file = "C:\InterSystems\Cache\mgr\user\Test.xml") As %XML.Document
{
set reader=##class(%XML.Reader).%New()
set status=reader.OpenFile(file)
if $$$ISERR(status) {do $System.Status.DisplayError(status) quit $$$NULLOREF}
#dim document as %XML.Document
set document=reader.Document
#; set reNo=##class(%XML.Node).%New() //check here
#; set reNo.Document=document //check here
#; do ..ShowNode(reNo)
do ..ShowNamespaces(document)
#dim node as %XML.Node
set %lev=0
set node=document.GetDocumentElement()
do ..Analyze(node)
quit document
}
ClassMethod Analyze(node As %XML.Node)
{
set hasChild =..ShowNode(node)
set attribute=node.FirstAttributeName()
while attribute'="" {
do ..ShowAttribute(.attribute,node)
}
if hasChild {
set tSC=node.MoveToFirstChild(1)
if tSC , $i(%lev) {
while tSC {
do ..Analyze(node)
set tSC=node.MoveToNextSibling(1)
}
do node.MoveToParent() if $i(%lev,-1)
}
}
quit
}
ClassMethod ShowAttribute(ByRef attribute, node As %XML.Node)
{
write !?(%lev+1*3),"Attribute_Name ",attribute
,!?(%lev+1*3),"Atribute_Value ",node.GetAttributeValue(attribute)
#; more to be added here
,!?(%lev+1*3),"--------------------------"
set attribute=node.NextAttributeName(attribute)
quit
}
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)
}
}
// how to use the below method
ClassMethod ShowNode(node As %XML.Node) As %Boolean
{
If node.NodeType=$$$xmlELEMENTNODE {
Write !?(%lev*3),"LocalName="_node.LocalName
#; Write !,"Namespace="_node.Namespace
#; }
#; If node.NodeType=$$$xmlELEMENTNODE {
#; Write !,"NamespaceIndex="_node.NamespaceIndex
Write !?(%lev*3),"Nil="_node.Nil
Write !?(%lev*3),"NodeData="_node.NodeData
Write !?(%lev*3),"QName="_node.QName
}
Write !?(%lev*3),"NodeId="_node.NodeId
Write !?(%lev*3),"NodeType="_node.NodeType
Write !?(%lev*3),"HasChildNodes returns "_node.HasChildNodes()
If node.NodeType=$$$xmlELEMENTNODE {
Write !?(%lev*3),"GetNumberAttributes returns "_node.GetNumberAttributes()
Set status=node.GetText(.text)
If status {
Write !?(%lev*3), "Text of the node is "_$tr(text,$c(10))
} else {
Write !?(%lev*3), "GetText does not return text"
}
}
quit node.HasChildNodes()
}
}