Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Not getting data using XMLAdapter

Status
Not open for further replies.

CBellucci

Programmer
Apr 20, 2007
38
US
Hello all!

I have the following XSD (library.xsd):
Code:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="[URL unfurl="true"]http://www.w3.org/2001/XMLSchema">[/URL]
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="author" type="xs:string"/>
        <xs:element name="character" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name" type="xs:string"/>
              <xs:element name="friend-of" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
              <xs:element name="since" type="xs:date"/>
              <xs:element name="qualification" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="isbn" type="xs:string"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

And the following xml (books.xml):
Code:
<?xml version="1.0" encoding="utf-8" ?> 
<book isbn="0836217462" xmlns:xsi="[URL unfurl="true"]http://www.w3.org/2001/XMLSchema-instance"[/URL] xsi:noNamespaceSchemaLocation="library.xsd">
  <title>Being a Dog Is a Full-Time Job</title> 
  <author>Charles M. Schulz</author> 
  <character>
     <name>Snoopy</name> 
     <friend-of>Peppermint Patty</friend-of> 
     <since>1950-10-04</since> 
     <qualification>extroverted beagle</qualification> 
  </character>
  <character>
     <name>Peppermint Patty</name> 
     <since>1966-08-22</since> 
     <qualification>bold, brash and tomboyish</qualification> 
  </character>
</book>

And the following VFP9 code:
Code:
LOCAL loAdapter as XMLAdapter

loXMLAdapter = CREATEOBJECT("XMLAdapter")
jcFile = "BOOKS.XML"
jcXSDFile = "LIBRARY.XSD"

loXMLAdapter.XMLSchemaLocation = jcXSDFile
*loXMLAdapter.RespectNesting = .T.

IF loXMLAdapter.LoadXML(M.jcFile, .T., .T.)
  ? "The Number of Tables Read is " + TRANSFORM(loXMLAdapter.Tables.Count)
  IF loXMLAdapter.Tables.Count > 0
    FOR jnIndx = 1 TO loXMLAdapter.Tables.Count
      ? "Table " + LTRIM(STR(M.jnIndx)) + ": " + loXMLAdapter.Tables[M.jnIndx].Alias
      loXMLAdapter.Tables.Item[M.jnIndx].ToCursor()
      BROWSE
    ENDFOR
  ENDIF
ENDIF

loXMLAdapter = .NULL.
RETURN

Now, from all that, the program reports that I have 2 tables. Table 1 is character and table 2 is book. From the browse, the character table gets propagated with data that I can see. The browse for book, table 2, shows up with the proper fields, but no data. I've also done this test on other xsd files and xml, and if I only have one table defined in the xml, the data never reaches the table.

What am I missing?
 
I get the same as you, an empty book cursor. Maybe XMLAdapter can't cope with this schema anyway, as isbn is an attribute, while author and title are elements, but tocursor also fails, if I first remove the isbn field from that xmltable.

You can get the book data as follows:

Code:
* after loadxml:
With loXMLAdapter.IXMLDOMElement
? .selectNodes("//book").item(0).attributes.item(0).name
? .selectNodes("//book").item(0).attributes.item(0).text
? .selectNodes("//book/title").item(0).text
? .selectNodes("//book/author").item(0).text
Endwith

This can be generalized a bit, as you cen retrieve attribute and element names to build the expressions for selectNodes from the XML itself, but this leads to less elegant code than parsing the xml yourself via eg StrExtract().

You could also load the xml using Msxml2.DOMDocument.6.0, but this will even less help, as it has no XMLTables collection, not to speak of a tocursor functionality.

At least the XML and ASD are valid, that's not the problem. And in general XMLAdapter can cope with nested XML, as Sergey Berezniker has shown here:

Bye, Olaf.
 
Interesting, because the XSD and XML came from a Hentzenwerke sample for "What's New in Visual FoxPro 9.0" -- and I would think that the XSD and XML would have been tested to work... but maybe not.

And I have the same problem with other XML in that sample and with other XSD/XML that we have we need to use.

Is there something that can be added either in the XSD or the XML to get it to work?
 
Is it a glitch of SP1 or 2 perhaps? I don't think there were any changes in XMLAdapter, it mainly uses MSXML4 anyway, but that may be a reason.

Well, you could change the schema to let isbn also be an element instead of an attribute and then see, if it works.

But if that is an academic example, it may not be worth the hassle to make it work. You can take Sergeys sample and see it only works with elements.

But as long as you have no influence over the schema of xml coming in from elsewhere, concetrate on that real world problems. Solving this one will not solve the issues you're having with other schemas.

There are many third party tools availble for handling XML, parsers etc., don't reinvent the wheel.

Bye, Olaf.
 
I can't get my real-life XML to read in, either. So I went back to examples to build my knowledge, and the examples don't work.

I'm beginning to believe it's the XML itself.
 
I can't help you with only knowing the examples you're learning from partially. Ask back to the books authors, perhaps. Tamar might be able to set this straight as she also reads and answers questions here.

ONe thing is for sure: There is no single code to transform any XML into a set of tables. There is code converting any XML to tables, but not necessarily in the structure you'd want them in the end. What always can be done is seeing at the xml as a tree strucutre of nodes, some of them having child nodes, some being root nodes, others beeing leaf nodes and put that into a genral table structure as: id, nodename, nodedata, parentnode.

Pavel Celba has developed such a xmltotable transformation displaing a sample result here:

You may contact him in the MSDN forums, if you like that idea, but the consequence is, the dbf result would have a record for each single field value in the xml and you'd need to pull data together in the cursor structure you need via postprocessing that. You may get your head around that easier than around XML, but actually it's just transforming the xml into a dbf representation of the same form, it always ends up in one dbf of all the xml elements and their attributes and parent/child relationship.

Bye, Olaf.
 
I'm sure it was tested when we wrote the book. Jim was a really good tech editor and pushed us on stuff.

Okay, I see that the example using that schema doesn't actually call ToCursor. It just loads the XML and reports the number of tables. The point of this example is that VFP 8 couldn't even do that.

I didn't write that chapter or the example, so I'm not sure whether ToCursor should work.

Tamar
 
Hi Tamar,

CBellucci spooke of "What's New in Visual FoxPro 9.0" and not of 8.0, but besides that, if he added to the sample code, it's no error of the book, of course.

@CBellucci, the XML and XSD are valid, but you may misunderstand what an XSD schema is for. It is just describing the general structure/schema of the XML file and can be used to verify the XML, it's not defining a table schmea translating from the XML to a table structure.

I tested you XSD and XML via and uploaded your library.xsd and books.xml as files.

Also The LoadXML includes validation and confirms the XML is valid against the XSD.

Besides that the code example I gave to read in the books field values one by one get's the correct values out of the IXMLDOMElement. If it wasn't valid, the XMLAdapter wouldn't have a filled IXMLDOMElement object, the XML wouldn't be loaded into a document object model, which the IXMLDOMElement is.

What you can criticise towards the XMLAdapter is it detecting both the character and book table into the XMLTables collection including their correct structure, but then not reading in the book record. But it's also unusual to have some data in elements, and others in attributes.

In the end XML is just text, you can always write code extracting the informations you need out of it, it's just cumbersome, but always possible.

Bye, Olaf.
 
After this exercise, I'm rethinking the use of the XMLAdapter. I'll be looking at your suggestions to try to get something to work.

Thanks, all!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top