what would cause xmlreader to skip an element

Importing XML into Caché Objects

This topic describes how to use the %XML.Reader class to import XML documents into Caché objects. It discusses the following items:

  • An overview and a simple case

  • How to create an import method and the basic construction of such a method, with an case

  • How to bank check for required elements and attributes

  • How to handle unexpected elements and attributes

  • How to handle empty elements and attributes

  • How to skip before parts of the input document

  • Other methods that you use less frequently

  • Other backdrop that you can set to control the overall behavior of the reader

  • How to customize how the reader behaves when information technology finds a correlated object

  • Boosted examples

Note:

The XML declaration of any XML document that you use should indicate the character encoding of that document, and the document should exist encoded equally declared. If the character encoding is not declared, Caché uses the defaults described in "Character Encoding of Input and Output," earlier in this book. If these defaults are not correct, change the XML declaration so that it specifies the grapheme set up actually used.

You can too utilise %XML.Reader to read an arbitrary XML document and return a DOM (Document Object Model); see the topic "Representing an XML Document as a DOM," later in this book.

Overview of Creating an XML Reader

Caché provides tools for reading an XML document and creating one or more than instances of XML-enabled Caché objects that stand for to elements of that document. The essential requirements are every bit follows:

  • The course definition for that object must extend %XML.Adaptor . With a few exceptions, the classes to which that object refers must also extend %XML.Adaptor . See Projecting Objects to XML.

    Tip:

    If the respective XML schema is available, yous can use that to generate the course (and whatever supporting classes). Come across the topic "Generating Classes from XML Schemas," later in this book.

  • To import the XML document, create an instance of %XML.Reader and then invoke methods of that instance. These methods specify the XML source document, associate an XML element with an XML-enabled class, and read elements from the source into objects.

The %XML.Reader class works with the methods provided by the %XML.Adaptor form to exercise the post-obit:

  • It parses and validates the incoming XML document using the Caché SAX interface. The validation can include either DTD or XML Schema validation.

  • It determines if any XML-enabled objects are correlated with the elements contained within the XML document and creates in-memory instances of these objects equally information technology reads the document.

Annotation that the object instances created by %XML.Reader are non stored within the database; they are in-memory objects. If you want to store objects within the database, y'all must call the %Save() method (for persistent objects) or copy the relevant property values to a persistent object and save information technology. The application must too make up one's mind when to insert new information and when to update existing information; %XML.Reader has no way of making this distinction.

The following Last session shows a simple example. Here nosotros read an XML file into a new object, examine that object, so relieve that object:

GXML>Prepare reader = ##class(%XML.Reader).%New()   GXML>Ready file="c:\sample-input.xml"   GXML>Ready status = reader.OpenFile(file)   GXML>Write condition 1 GXML>Do reader.Correlate("Person","GXML.Person")   GXML>Practice reader.Next(.object,.status)   GXML>Write status 1 GXML>Write object.Name Worthington,Jeff R. GXML>Write object.Doctors.Count() 2 GXML>Do object.%Save()

This example uses the following sample XML file:

              <              Person                                          GroupID              =              "90455"              >                                          <              Proper name              >              Worthington              ,              Jeff                                          R.              </              Name              >                                          <              DOB              >              1976-11-03              </              DOB              >                                          <              Accost              >                                          <              Urban center              >              Elm                                          City              </              Urban center              >                                          <              Aught              >              27820              </              Aught              >                                          </              Address              >                                          <              Doctors              >                                          <              Doctor              >                                          <              Name              >              All-time              ,              Nora                                          A.              </              Name              >                                          </              Doctor              >                                          <              Doctor              >                                          <              Name              >              Weaver              ,              Dennis                                          T.              </              Name              >                                          </              Doc              >                                          </              Doctors              >              </              Person              >            

Creating an Import Method

Overall Method Construction

Your method should do some or all of the following, in this club:

  1. Create an instance of the %XML.Reader class.

  2. Optionally specify the Format property of this instance, to specify the format of the file that yous are importing; come across "Reader Properties."

    By default, Caché assumes that XML files are in literal format. If your file is in Soap-encoded format, you must indicate this then that the file can be read correctly.

  3. Optionally gear up other properties of this instance; see "Reader Properties."

  4. Open the source. To do and so, use one of the following methods of %XML.Reader :

    • OpenFile() — Opens a file.

    • OpenStream() — Opens a stream.

    • OpenString() — Opens a cord.

    • OpenURL() — Opens a URL.

      If the URL uses HTTPS, see "Accessing a Document at an HTTPS URL," later in this topic.

    In each case, you tin can optionally specify a second argument for the method, to override the value of the Format property.

  5. Correlate 1 or more XML element names in this file with Caché XML-enabled classes that take the corresponding structures. There are two ways to practice this:

    • Use the Correlate() method, which has the following signature:

      method Correlate(element As %Cord,                   class As %String,                   namespace As %String)

      Where element is an XML element name, course is a Caché class proper name (with package), and namespace is an optional namespace URI.

      If you use the namespace argument, the match is restricted to the specified element proper noun in the specified namespace. If you specify the namespace argument as "", that matches the default namespace given in the Next() method. If you practice not utilize the namespace argument, and so only the chemical element name is used for the match.

      Tip:

      Y'all tin can telephone call the Correlate() method repeatedly to correlate more than one element, although the examples in this topic show just ane correlation.

    • Use the CorrelateRoot() method, which has the post-obit signature:

      method CorrelateRoot(class As %Cord)

      Where class is a Caché grade name (with packet). This method specifies that the root element of the XML document is correlated to the specified form.

  6. Instantiate the class instances as follows:

    • If you used Correlate(), loop through the correlated elements in the file, one element at a time. Inside the loop, apply the Adjacent() method, which has the following signature:

      method Next(ByRef oref Equally %ObjectHandle,              ByRef sc As %Status,              namespace As %String = "") every bit %Integer

      Where oref is the object created by the method, sc is the status, and namespace is the default namespace for the file.

    • If you lot used CorrelateRoot(), phone call the Adjacent() method once, which causes the correlated course to be instantiated.

    The Next() method returns 0 when it reaches the end of the file. If you call Side by side() again after this, y'all will loop through the objects in the file over again, starting at the pinnacle of the file. (The correlations you specified are still in effect.)

Error Checking

Most of the methods mentioned in the previous section render a status. Yous should bank check the status after each step and quit if advisable.

Basic Import Case

Consider the post-obit XML file chosen test.xml:

                <                Root                >                                                <                Person                >                                                <                Name                >                Elvis                                                Presley                </                Proper name                >                                                </                Person                >                                                <                Person                >                                                <                Name                >                Johnny                                                Carson                </                Proper name                >                                                </                Person                >                </                Root                >              

We start past defining an XML-enabled class, MyApp.Person, that is an object representation of a person:

                Class                                                MyApp                .                Person                                                Extends                                                (                %Persistent                ,                %XML                .                Adaptor                )                {                Parameter                                                XMLNAME                                                =                                                "Person"                ;                Holding                                                Name                                                Equally                                                %Cord                ;                }              

To import this file into an instance of a MyAppPerson grade, we could write the post-obit method:

                ClassMethod                                                Import                ()                {                                                // Create an instance of %XML.Reader                                                Prepare                                                reader                                                =                                                ##class                (                %XML                .                Reader                )                .                %New                (                )                                                // Begin processing of the file                                                Set                                                status                                                =                                                reader                .                OpenFile                (                "c:\test.xml"                )                                                If                                                $$$                ISERR                (                status                )                                                {                do                                                $System                .                Condition                .                DisplayError                (                status                )                }                                                // Associate a class proper name with the XML chemical element name                                                Do                                                reader                .                Correlate                (                "Person"                ,                "MyApp.Person"                )                                                                                // Read objects from xml file                                                While                                                (                reader                .                Next                (                .                object                ,                .                status                )                )                                                {                                                Write                                                object                .                Name                ,                !                                                }                                                                                // If error found during processing, show it                                                If                                                $$$                ISERR                (                status                )                                                {                do                                                $System                .                Status                .                DisplayError                (                condition                )                }                }              

This method performs several tasks:

  • Information technology parses the input file using the Caché SAX interface. This includes validating the certificate confronting its DTD or schema, if specified.

  • The Correlate() method assembly the grade MyApp.MyPerson with the XML element <Person>; each child element in <Person> becomes a belongings of MyPerson.

  • It reads each <Person> element from the input file until there are none left.

  • Finally, if the loop terminates because of an fault, the error is displayed on the current output device.

Every bit mentioned above, this example does not store objects to the database. Because MyPerson is a persistent object, you could do this by calculation the following lines inside the While loop:

                                                Set                                                savestatus                                                =                                                object                .                %Save                (                )                                                If                                                $$$                ISERR                (                savestatus                )                                                {                exercise                                                $System                .                Status                .                DisplayError                (                savestatus                )                }              

Accessing a Document at an HTTPS URL

For the OpenURL() method, if the document is at a URL that requires SSL/TLS, practise the post-obit:

  1. Use the Management Portal to create an SSL/TLS configuration that contains the details of the needed connection. For data, see the topic "Using SSL/TLS with Caché" in the Caché Security Administration Guide.

    This is a one-fourth dimension step.

  2. When you use %XML.Reader , prepare the SSLConfiguration property of the reader case. For the value, specify the name of the SSL/TLS configuration that y'all created in the previous step.

Or, when y'all use %XML.Reader , as well practise the following:

  1. Create an case of %Cyberspace.HttpRequest .

  2. Set the SSLConfiguration property of that instance equal to the configuration name of the SSL/TLS configuration that you created in the Management Portal.

  3. Apply that instance of %Internet.HttpRequest as the 3rd statement to OpenURL().

For example:

                                                set                                                reader                =                ##class                (                %XML                .                Reader                )                .                %New                (                )                                                                                ready                                                httprequest                =                ##form                (                %Cyberspace                .                HttpRequest                )                .                %New                (                )                                                                                set                                                httprequest                .                SSLConfiguration                =                "mysslconfigname"                                                                                set                                                condition                =                reader                .                OpenURL                (                "https://myurl"                ,                ,                httprequest                )                                              

Accessing a Document When the Server Requires Hallmark

If the server requires authentication, create an instance of %Net.HttpRequest and set the Username and Password backdrop of that case. Besides use SSL as described above (and so also set the SSLConfiguration property). Then use that case of %Net.HttpRequest as the third argument to OpenURL() as shown in the example above.

For more details on %Net.HttpRequest and authentication, see "Providing Login Credentials" in the topic "Sending HTTP Requests" in Using Caché Internet Utilities.

Checking for Required Elements and Attributes

By default, the Side by side() method does not cheque for the existence of elements and attributes that stand for to backdrop that are marked every bit Required. To cause the reader to check for the existence of such elements and attributes, set the CheckRequired property of the reader to i earlier calling Next(). The default value for this property is 0, for compatibility reasons.

If yous ready CheckRequired to ane, and if you call Next() and the imported XML is missing a required element or attribute, the Adjacent() method sets the sc argument to an error code. For instance:

SAMPLES>set adjacent= reader.Side by side(.object,.status)   SAMPLES>w next 0 SAMPLES>d $system.Status.DisplayError(status)   ERROR #6318: Holding required in XML certificate: ReqProp

Handling Unexpected Elements and Attributes

Because the source XML documents might incorporate unexpected elements and attributes, the %XML.Adaptor course provides parameters to specify how to react when yous import such a certificate. For details, meet the topic "Special Topics" in Projecting Objects to XML.

Controlling How Empty Elements and Attributes Are Imported

When you XML-enable an object, yous specify how cypher values and empty strings are projected to XML (see Projecting Objects to XML).

One of the options is to set XMLIGNORENULL equal to "RUNTIME" (not case-sensitive) in the XML-enabled class. In this case, when yous use %XML.Reader to read an XML file and create Caché objects, Caché uses the value of the IgnoreNull property of the reader to determine how to handle empty elements or attributes, as follows:

  • If the IgnoreNull belongings of the reader is 0 (the default), and an chemical element or attribute is empty, the respective property is set equal to $char(0)

  • If the IgnoreNull belongings of the reader is 1, and an element or attribute is empty, the corresponding property is not set up and therefore equals ""

The IgnoreNull property of the reader has no effect unless the XMLIGNORENULL is "RUNTIME" in the XML-enabled grade; the other possible values for XMLIGNORENULL are 0 (the default), 1, and "INPUTONLY"; see Projecting Objects to XML.

Example: IgnoreNull Is 0 (Default)

Commencement, consider the following class:

                Class                                                EmptyStrings                .                Import                                                Extends                                                (                %Persistent                ,                                                %XML                .                Adaptor                )                {                Parameter                                                XMLNAME                =                "Test"                ;                ///                Reader volition fix IgnoreNull property                Parameter                                                XMLIGNORENULL                                                =                                                "RUNTIME"                ;                Property                                                PropertyA                                                As                                                %String                ;                Property                                                PropertyB                                                As                                                %String                ;                Property                                                PropertyC                                                As                                                %String                ;                Property                                                PropertyD                                                As                                                %String                (                XMLPROJECTION                                                =                                                "ATTRIBUTE"                )                ;                Property                                                PropertyE                                                As                                                %Cord                (                XMLPROJECTION                                                =                                                "Aspect"                )                ;                }              

Also consider the following XML file:

                <?                xml                                                version                =                "one.0"                                                encoding                =                "UTF-8"                ?>                <                Test                                                PropertyD                =                ""                >                                                <                PropertyA                >                </                PropertyA                >                                                <                PropertyB                                                xsi:nil                =                "true"                                                                                xmlns:xsi                =                "http://www.w3.org/2001/XMLSchema-case"                />                </                Test                >              

If y'all create an instance of %XML.Reader and apply information technology to import this file into the previous form, you get the post-obit effect:

  • PropertyA and PropertyD equal $char(0).

  • All other backdrop equal "".

For instance, if you wrote a routine to examine each holding, inspect its value, and write output, you might go something like the post-obit:

PropertyA is $char(0) PropertyB is nix PropertyC is cypher PropertyD is $char(0) PropertyE is nil

Instance: IgnoreNull Is 1

In a variation of the preceding case, we set the IgnoreNull property of the reader equal to 1. In this case, all backdrop equal "".

For case, if you wrote a routine to examine each property, inspect its value, and write output, you might get something like the following:

PropertyA is nil PropertyB is null PropertyC is null PropertyD is cipher PropertyE is naught

Skipping Earlier Parts of the Input Document

An XML document consists of a prepare of nodes; the root node is numbered 0, the showtime element inside that is numbered 1, and then on. You can specify the node at which to start reading; this is specially useful for large documents. To do so, set the Node property of the reader. For the value, specify an integer.

An instance method follows:

              ClassMethod                                          DemoSkippingAhead              (              nodenumber                                          equally                                          %Integer              =              0              )              {                                          Set                                          cls              =              "GXML.Person"                                          Set up                                          filename              =              "c:\GXML.Person.xml"                                          Set                                          chemical element              =              "Person"                                          // Create an instance of %XML.Reader                                          Set                                          reader                                          =                                          ##class              (              %XML              .              Reader              )              .              %New              (              )                                          // Begin processing of the file                                          Set                                          status                                          =                                          reader              .              OpenFile              (              filename              )                                          If                                          $$$              ISERR              (              status              )                                          {              Do                                          $System              .              Status              .              DisplayError              (              status              )              }                                          // Associate a course name with the XML element name                                          Do                                          reader              .              Correlate              (              element              ,              cls              )                                                                      //skip ahead in the file                                          Set                                          reader              .              Node              =              nodenumber                                          // Read objects from xml file                                          While                                          (              reader              .              Next              (              .              object              ,              .              condition              )              )                                          {                                          Write                                          "Node number "              _              reader              .              Node              _              " contains "              _              object              .              Proper noun              ,              !                                          }              }            

This method assumes a specific input file, grade proper name, and element name. By default, this method starts at the beginning of the file. For instance:

GXML>d ##course(Readers.ReadFile).DemoSkippingAhead() Node number 3 contains Emerson,Republic of chad I. Node number xxx contains O'Rielly,Patricia L. Node number 63 contains Hanson,Brendan T. Node number 120 contains Orwell,Tara H. Node number 195 contains Gilt,Elvis O. Node number 234 contains Klein,Brenda U. Node number 252 contains Yezek,Kristen Q. Node number 327 contains Quine,Angelo B. Node number 378 contains Vivaldi,Milhouse J. Node number 453 contains Yezek,Vincent D. Node number 471 contains Xander,Juanita D. Node number 522 contains Winters,Kyra R. Node number 555 contains Woo,Michelle J. Node number 636 contains Ihringer,Yan A. Node number 654 contains W,Hannah N. Node number 729 contains Xiang,Bob G. Node number 762 contains Ximines,Howard H. Node number 789 contains Quixote,Jocelyn P. Node number 864 contains Hills,Charles Due east. Node number 897 contains Evans,Milhouse R.

In contrast, we could skip ahead as follows:

GXML>d ##class(Readers.ReadFile).DemoSkippingAhead(700) Node number 729 contains Xiang,Bob Grand. Node number 762 contains Ximines,Howard H. Node number 789 contains Quixote,Jocelyn P. Node number 864 contains Hills,Charles Eastward. Node number 897 contains Evans,Milhouse R.

Other Useful Methods

On occasion, you may need to use the following additional methods of %XML.Reader :

  • Utilise the Rewind() method if you demand to restart reading from the start of the XML source document. This method clears all correlations.

  • Utilise the Shut() method if you want to explicitly close and clean up the import handler. The import handler is cleaned up automatically; this method is included for backward compatibility.

Reader Properties

Yous can set the following backdrop of %XML.Reader to control the overall behavior of your method:

  • Use the UsePPGHandler property to specify whether the instance of %XML.Reader uses process-individual globals when it parses the document. If this property is true, the instance uses process-private globals. If this property is simulated, the instance uses memory. If this belongings is non set up (or equals an empty string), the instance uses the default, which is normally memory.

    Apply the Format holding to specify the overall format of the XML certificate. Specify one of the post-obit values:

    • "literal", the default, which is used in most of the examples in this topic.

    • "encoded", encoded as described in the SOAP ane.1 standard.

    • "encoded12", encoded as described in the Soap 1.ii standard.

    Note that you can override the Format property inside the OpenFile(), OpenStream(), OpenString(), and OpenURL() methods.

    This belongings has no effect unless yous use Correlate() and Side by side().

  • Use the Summary belongings to force the reader to import simply the summary fields of the XML-enabled objects. Every bit noted in Projecting Objects to XML, the summary of an object is specified by its XMLSUMMARY class parameter, which y'all specify as a comma-separated list of properties.

  • Use the IgnoreSAXWarnings property to specify whether the reader should report warnings issued past the SAX parser.

%XML.Reader likewise provides properties that you lot tin use to examine the document you are reading:

  • The Document holding contains an instance of %XML.Document that represents the entire, parsed certificate that yous are reading. For information on %XML.Document , see the class reference.

  • The Node property is a string that represents the current node of the XML document. Notation that 0 ways the certificate, that is, the parent of the root element.

For information on the EntityResolver, SAXFlags, and SAXSchemaSpec properties, come across the topic "Customizing How the SAX Parser Is Used." Note that the SAXMask belongings is ignored.

Redefining How the Reader Handles Correlated Objects

When an instance of %XML.Reader finds an XML element that is correlated to an XML-enabled course, the reader calls the XMLNew() method of that class, which in plow calls %New() by default. That is, when a reader finds a correlated element, it creates a new object of the correlated class. The new object is populated with the information that y'all read from the XML document.

Yous tin can customize this behavior by redefining XMLNew() in your XML-enabled class (or perhaps in your own custom XML adaptor). For case, this method can instead open an existing instance of that class. The existing case then receives the data that you read from the XML document.

The following examples evidence how you can modify XMLNew() to update existing instances with new data from an XML document.

In both examples, for simplicity, we assume that a node in the XML document contains an ID that we can compare to the IDs in the extent for the class. Nosotros could of course compare the XML document to the existing objects in other ways.

When %XML.Reader Calls XMLNew()

For reference, %XML.Reader calls the XMLNew() method automatically in two circumstances:

  • %XML.Reader calls XMLNew() when you call the Next() method of %XML.Reader , after you have correlated XML elements (in an external document) with an XML-enabled class. The Side by side() method gets the adjacent element from the certificate, calls XMLNew() to create an case of the appropriate object, and then imports the chemical element into the object.

  • Similarly, %XML.Reader calls XMLNew() for any object-valued properties of the correlated XML elements.

Example 1: Modifying XMLNew() in an XML-Enabled Grade

First consider the following XML file:

<?xml version="1.0" encoding="UTF-viii"?> <root>   <Person>     <CacheID>4</CacheID>     <Name>Quine,Maria Chiliad.</Name>     <DOB>1964-11-14</DOB>     <Accost>       <City>Hialeah</City>       <Naught>94999</Zip>     </Accost>     <Doctors>       <Doctor>         <Name>Vanzetti,Debra B.</Name>       </Md>     </Doctors>   </Person> ...

This file maps to the post-obit Caché class (partly shown):

                Class                                                GXML                .                PersonWithXMLNew                                                Extends                                                (                %Persistent                ,                %Populate                ,                %XML                .                Adaptor                )                {                Parameter                                                XMLNAME                =                "Person"                ;                ///                                                make sure this is the same as the XMLNAME of the property                                ///                                                in this class that is of type %XML.Id                Parameter                                                CACHEID                                                As                                                %String                                                =                                                "CacheID"                ;                Property                                                IdForExport                                                As                                                %XML                .                Id                (                XMLNAME                =                "CacheID"                ,                XMLPROJECTION                =                "ELEMENT"                )                                                [                Individual                ,                Transient                ]                ;                Property                                                Name                                                Equally                                                %Name                ;                Property                                                DOB                                                As                                                %Date                (                FORMAT                                                =                                                5                ,                                                MAXVAL                                                =                                                "+$h"                )                ;                Property                                                Address                                                Every bit                                                GXML                .                Address                ;                Property                                                Doctors                                                As                                                list                                                Of                                                GXML                .                Doc                ;                }              

In this class, the purpose of the IdForExport property is to project the Caché internal ID to an chemical element (CacheID) when objects of this class are exported. (In this detail case, this enables us to easily generate suitable files for import. Your grade does not take to contain such a property.)

The CACHEID parameter is used to point the element that nosotros use for the Caché ID when we export objects of this class. This is included only for the convenience of the customized XMLNew() method that we take also added to this course. This method is defined as follows:

                ClassMethod                                                XMLNew                (                md                                                As                                                %XML                .                Document                ,                                                node                                                Every bit                                                %Integer                ,                                                contOref                                                Every bit                                                %RegisteredObject                                                =                                                ""                )                                                Every bit                                                GXML                .                PersonWithXMLNew                {                                                Set up                                                id                =                ""                                                Set                                                tmpnode                =                doc                .                GetNode                (                node                )                                                Do                                                tmpnode                .                MoveToFirstChild                (                )                                                Do                                                {                                                //compare data node to the string given past the CACHEID parameter                                                //which indicates the XMLNAME of the ids for this object                                                If                                                tmpnode                .                NodeData                =                ..                #                CACHEID                                                {                                                //become the text from this node; this corresponds to an id in Cache                                                Do                                                tmpnode                .                GetText                (                .                id                )                }                                                }                                                While                                                tmpnode                .                MoveToNextSibling                (                )                                                                                //if at that place is no id in the given node, create a new object                                                If                                                id                =                ""                                                {                                                Write                                                !                ,                                                "Creating a new object..."                                                Quit                                                ..                %New                (                )                }                                                                                //open up the given object                                                Set                                                result                =                ..                %OpenId                (                id                )                                                                                //if the id doesn't stand for to an existing object, create a new object                                                If                                                consequence                =                $$$                NULLOREF                                                {                                                Write                                                !                ,                                                "Creating a new object..."                                                                                Quit                                                ..                %New                (                )                }                                                Write                                                !                ,                                                "Updating an existing object..."                                                Quit                                                event                }              

%XML.Reader calls this method when it reads an XML certificate and correlates a node to GXML.PersonWithXMLNew. This method looks at the value of the CACHEID parameter in this class, which is CacheID. It then examines the node in the document with the element CacheID and gets its value.

If this ID corresponds to an existing object of this class, the method opens that instance. Otherwise, the method opens a new instance of this class. In both cases, the example receives the properties as specified in the XML certificate.

Finally, the following utility class includes a method that opens the XML file and calls %XML.Reader :

                Course                                                GXML                .                DemoXMLNew                                                Extends                                                %RegisteredObject                {                ClassMethod                                                ReadFile                (                filename                                                As                                                %String                                                =                                                "c:\temp\sample.xml"                )                {                                                Set up                                                reader                =                ##class                (                %XML                .                Reader                )                .                %New                (                )                                                Set                                                sc                =                reader                .                OpenFile                (                filename                )                                                If                                                $$$                ISERR                (                sc                )                                                {                Practice                                                $system                .                OBJ                .                DisplayError                (                sc                )                                                Quit                                                }                                                                                Do                                                reader                .                Correlate                (                "Person"                ,                "GXML.PersonWithXMLNew"                )                                                                                //loop through elements in file                                                                While                                                reader                .                Next                (                .                person                ,                .                sc                )                                                {                                                Write                                                !                ,                person                .                Proper noun                ,                !                                                Set                                                sc                =                person                .                %Save                (                )                                                If                                                $$$                ISERR                (                sc                )                                                {                Practise                                                $organization                .                OBJ                .                DisplayError                (                sc                )                                                Quit                                                }                                                }                                                Quit                }                }              

When you run the preceding method, one of the post-obit occurs for each <Person> chemical element in the file:

  • An existing object is opened, updated with details from the file, and saved.

  • Or a new object is created, with details from the file.

For example:

GXML>d ##class(GXML.DemoXMLNew).ReadFile()   Updating an existing object... Zampitello,Howard I.   Creating a new object... Smyth,Linda D.   Creating a new object... Vanzetti,Howard I.              

Case 2: Modifying XMLNew() in a Custom XML Adaptor

In the second example, we create a custom XML adaptor to perform the same actions as shown in the first example. The adaptor course is equally follows:

                Class                                                GXML                .                AdaptorWithXMLNew                                                Extends                                                %XML                .                Adaptor                {                ///                                                make sure this is the same every bit the XMLNAME of the property in this class                ///                                                that is of type %XML.Id                Parameter                                                CACHEID                                                As                                                %String                                                =                                                "CacheID"                ;                Property                                                IdForExport                                                Equally                                                %XML                .                Id                (                XMLNAME                =                "CacheID"                ,                XMLPROJECTION                =                "ELEMENT"                )                                                [                Individual                ,                Transient                ]                ;                ClassMethod                                                XMLNew                (                document                                                As                                                %XML                .                Document                ,                                                node                                                As                                                %Integer                ,                                                containerOref                                                Every bit                                                %RegisteredObject                                                =                                                ""                )                                                As                                                %RegisteredObject                                                [                CodeMode                =                objectgenerator,                GenerateAfter                =                %XMLGenerate                ,                ServerOnly                =                1]                {                                                If                                                %compiledclass                .                Name                '=                "GXML.AdaptorWithXMLNew"                                                {                                                Do                                                %code                .                WriteLine                (                " Set id="""""                )                                                Practice                                                %code                .                WriteLine                (                " Set tmpnode=document.GetNode(node)"                )                                                Do                                                %code                .                WriteLine                (                " Do tmpnode.MoveToFirstChild()"                )                                                Do                                                %code                .                WriteLine                (                " Do {"                )                                                Exercise                                                %code                .                WriteLine                (                "     If tmpnode.NodeData=..#CACHEID "                )                                                Do                                                %code                .                WriteLine                (                "       {Practice tmpnode.GetText(.id)}"                )                                                Practice                                                %code                .                WriteLine                (                " } While tmpnode.MoveToNextSibling() "                )                                                Do                                                %code                .                WriteLine                (                " If id="""" {"                )                                                Practise                                                %code                .                WriteLine                (                "  Write !,""Creating new object..."""                )                                                Do                                                %code                .                WriteLine                (                "  Quit ##class("                _                %class                .                Proper noun                _                ").%New()}"                )                                                Do                                                %lawmaking                .                WriteLine                (                " set issue=##class("                _                %class                .                Proper name                _                ").%OpenId(id)"                )                                                Do                                                %lawmaking                .                WriteLine                (                " If result=$$$NULLOREF {"                )                                                Do                                                %code                .                WriteLine                (                "     Write !,""Creating new object..."""                )                                                Do                                                %code                .                WriteLine                (                "     Quit ##class("                _                %class                .                Name                _                ").%New() }"                )                                                Exercise                                                %lawmaking                .                WriteLine                (                " Write !,""Updating existing object ..."""                )                                                Do                                                %code                .                WriteLine                (                " Quit outcome"                )                                                }                                                QUIT                                                $$$                OK                }                }              

The IdForExport property and the CACHEID parameter establish a convention for how we project the Caché internal ID to an element when objects of subclasses are exported. The intent is that if y'all redefine IdForExport in a subclass, you redefine CACHEID correspondingly.

In this class, the XMLNew() method is a method generator. When this form (or any subclass) is compiled, Caché writes the code shown here into the body of this method. Meet the topic "Method Generators" in Using Cache Objects.

The following form extends our custom adaptor:

                Form                                                GXML                .                PersonWithXMLNew2                                                Extends                                                (                %Persistent                ,                                                %Populate                ,                                                GXML                .                AdaptorWithXMLNew                )                {                Parameter                                                XMLNAME                                                =                                                "Person"                ;                Property                                                Proper name                                                As                                                %Proper name                ;                Property                                                DOB                                                As                                                %Engagement                (                FORMAT                                                =                                                v                ,                                                MAXVAL                                                =                                                "+$h"                )                ;                Holding                                                Address                                                As                                                GXML                .                Address                ;                Holding                                                Doctors                                                As                                                listing                                                Of                                                GXML                .                Doctor                ;                }              

When you run the sample ReadFile method shown earlier, for each <Person> element in the file, the method either creates and saves a new tape or opens and updates an existing tape.

Additional Examples

This section contains some additional examples.

Flexible Reader Grade

The following case shows a more flexible reader method that accepts the filename, directory, class, and chemical element every bit input arguments. The method saves each object that it reads.

                Class                                                Readers                .                BasicReader                                                Extends                                                %RegisteredObject                {                ClassMethod                                                Read                (                mydir                ,                                                myfile                ,                                                grade                ,                                                element                )                {                                                set                                                reader                =                ##form                (                %XML                .                Reader                )                .                %New                (                )                                                if                                                $extract                (                mydir                ,                $length                (                mydir                )                )                '=                "/"                                                {                set                                                mydir                =                mydir                _                "/"                }                                                set                                                file                =                mydir                _                myfile                                                set                                                status                =                reader                .                OpenFile                (                file                )                                                if                                                $$$                ISERR                (                condition                )                                                {                do                                                $System                .                Status                .                DisplayError                (                condition                )                }                                                do                                                reader                .                Correlate                (                chemical element                ,                class                )                                                while                                                reader                .                Next                (                .                object                ,                .                status                )                                                {                                                if                                                $$$                ISERR                (                status                )                                                {                do                                                $System                .                Status                .                DisplayError                (                status                )                }                                                gear up                                                condition                =                object                .                %Salve                (                )                                                if                                                $$$                ISERR                (                status                )                                                {                exercise                                                $System                .                Status                .                DisplayError                (                condition                )                }                                                }                }                }              

Notice that when you read in a Person object, yous automatically read in its corresponding Accost object. (And when you lot save the Person object, you automatically save the corresponding Address object equally well.) This is a adequately crude technique that would be suitable but for bulk load of data; it does non brand whatsoever endeavour to compare to or update existing data.

In order to use this method, you would demand an XML-enabled class whose projection matched the incoming XML document. Suppose that you had XML-enabled classes named MyApp.PersonWithAddress and MyApp.Address. Also suppose that you had an XML document equally follows:

                <?                xml                                                version                =                "1.0"                                                encoding                =                "UTF-8"                ?>                <                Root                >                                                <                Person                >                                                <                Proper noun                >                Able                ,                                                Andrew                </                Proper noun                >                                                <                DOB                >                1977-ten-06                </                DOB                >                                                <                Address                >                                                <                Street                >                6218                                                Clinton                                                Drive                </                Street                >                                                <                Metropolis                >                Reston                </                Metropolis                >                                                <                State                >                TN                </                State                >                                                <                Nix                >                87639                </                Aught                >                                                </                Address                >                                                </                Person                >                </                Root                >              

To read the objects in this file and save them to deejay, you would practise something similar the following:

                                                fix                                                dir                =                "C:\XMLread-these"                                                set                                                file                =                "PersonData.txt"                                                set                                                cls                =                "MyApp.PersonWithAddress"                                                set                                                chemical element                =                "Person"                                                practice                                                ##class                (                Readers                .                BasicReader                )                .                Read                (                dir                ,                file                ,                cls                ,                chemical element                )              

Reading a Cord

The post-obit method accepts an XML string, form, and element as input arguments. It saves each object that it reads.

                Course                                                Readers                .                BasicReader                                                Extends                                                %RegisteredObject                {                ClassMethod                                                ReadString                (                string                ,                                                class                ,                                                element                )                {                                                prepare                                                reader                =                ##class                (                %XML                .                Reader                )                .                %New                (                )                                                set                                                status                =                reader                .                OpenString                (                cord                )                                                if                                                $$$                ISERR                (                status                )                                                {                do                                                $System                .                Condition                .                DisplayError                (                status                )                }                                                do                                                reader                .                Correlate                (                chemical element                ,                class                )                                                while                                                reader                .                Next                (                .                object                ,                .                status                )                                                {                                                if                                                $$$                ISERR                (                status                )                                                {                practice                                                $System                .                Status                .                DisplayError                (                condition                )                }                                                set                                                status                =                object                .                %Save                (                )                                                if                                                $$$                ISERR                (                status                )                                                {                practise                                                $Arrangement                .                Status                .                DisplayError                (                status                )                }                                                }                }                }              

To use this method, you would practise something like the following:

                                                ready                                                cls                =                "MyApp.Person"                                                set                                                element                =                "Person"                                                do                                                ##class                (                Readers                .                BasicReader                )                .                ReadString                (                string                ,                cls                ,                element                )              

DocReleaseID: Core2018.1.7

hackerhinesself.blogspot.com

Source: https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GXML_IMPORT

0 Response to "what would cause xmlreader to skip an element"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel