XML Import Fails

Discussion forum for C++ and script developers who are using the QCAD development platform or who are looking to contribute to QCAD (translations, documentation, etc).

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files, scripts and screenshots.

Post one question per topic.

Post Reply
wildspidee
Full Member
Posts: 84
Joined: Sat Nov 03, 2012 2:00 am

XML Import Fails

Post by wildspidee » Fri Jan 23, 2015 12:43 am

Success! I have created the QT form and am saving the data in a persistent widget and in a new XML file (based on the ExXmlExport).

I have tried every type of XML file using the IOExamples>ExXmlImport and everything returns import failed at the command line. I tried XML with attributes and XML with elements only. Nothing works. I haven't messed with the code, it is the original provided in QCAD.

I read through the QT documentation, but the only thing I can find is that they say you have to set the Content Handler and the Error Handler. I tried adding that, but it didn't help.

Code: Select all

    xmlReader.setContentHandler(handler);
    xmlReader.setErrorHandler(handler);
Are you able to use this on XML files successfully?

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: XML Import Fails

Post by andrew » Fri Jan 23, 2015 9:56 am

Yes, this should work for all valid xml files. Can you attach or e-mail an xml file you are using to make sure we're on the same page? Thanks.

wildspidee
Full Member
Posts: 84
Joined: Sat Nov 03, 2012 2:00 am

Re: XML Import Fails

Post by wildspidee » Fri Jan 23, 2015 4:08 pm

I think the issue was me (big surprise). I was playing with the files in Text Edit, instead of my IDE (PHPStorm) and I think it was corrupting the file somehow. I just picked a random XML file off my machine and it worked. So I created a test file in the IDE based on that.

This is what I get back:

importing: /Users/lg/PhpstormProjects/QCAD-FM/Resources/scripts/FMScripts/FMMeasurements/importtest.xml
tag: resources
tag: msmt
attribute: name: CenterFrontF
tag: msmt
attribute: name: FullLengthF
tag: msmt
attribute: name: ShoulderSlopeF
import successful

The ExImport doesn't like element only XML, but that's fine. I can format my ExExport as attribute style. Per the code, I'm getting the localName - "name" and the value of that "CenterFrontF", but not the value of that attribute (22.34). What do I need to add to this line?

Code: Select all

 EAction.handleUserMessage("  attribute: " + atts.localName(i) + ": " + atts.value(i));
Attachments
importtest.xml
(194 Bytes) Downloaded 608 times

wildspidee
Full Member
Posts: 84
Joined: Sat Nov 03, 2012 2:00 am

Re: XML Import Fails

Post by wildspidee » Fri Jan 23, 2015 4:25 pm

Our time zone difference is bad (it's 7:20am here), so I'm trying to anticipate my issues for the day.

Another issue I'm anticipating is using the ExXmlImport scripts in my code. With the ExXmlExport, I was able to copy out the necessary code and just put it on one of my .js pages. I was surprised it worked, but it does.

The ExXmlImport is much more involved with more dependencies than the Export. I'll need the Import process at the top of my page to iterate the XML and place the values in my variables for use later in drawing. Can I create my own ExXmlImport that returns a multi-dimensional array within my FMMeasurements (sub folder with my drawing script) and then call asking for the array? Then I can loop the array and populate my variables?

How would I create this call and modify ExXmlImport to respond correctly? I know how to make the array and parse it, just need the code to call and return.

Thanks,
Lori

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: XML Import Fails

Post by andrew » Fri Jan 23, 2015 4:42 pm

First, let me recommend to structure your XML file differently (if you can):
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <resource name="CenterFrontF" measurement="22.34"/>
    <resource name="FullLengthF" measurement="45.86"/>
    <resource name="ShoulderSlopeF" measurement="34.38"/>
</resources>
Basically, you typically want to avoid having 'values' implemented as text (CDATA) nodes of an XML document. I'd recommend to represent numbers, IDs, names, etc. with XML attributes as above, not as text character data. One reason is that the resource tag above might have child tags one day. This would get really messy if there's text data and child tags mixed up... Personally, I'd only use text data for paragraphs of otherwise unstructured text, for example:
<description>This is a description</description>
If you do need text data, you can implement the characters function in your XML handler:
MyXmlHandler.prototype.characters = function(str) {
    // do something with str here...
};

wildspidee
Full Member
Posts: 84
Joined: Sat Nov 03, 2012 2:00 am

Re: XML Import Fails

Post by wildspidee » Fri Jan 23, 2015 4:47 pm

Changing the structure is no problem. Since I'm creating it with ExXmlExport I can make it any way I choose. I'll change my code and use your recommendation.

Thank you.

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: XML Import Fails

Post by andrew » Fri Jan 23, 2015 5:04 pm

wildspidee wrote:The ExXmlImport is much more involved with more dependencies than the Export. I'll need the Import process at the top of my page to iterate the XML and place the values in my variables for use later in drawing. Can I create my own ExXmlImport that returns a multi-dimensional array within my FMMeasurements (sub folder with my drawing script) and then call asking for the array? Then I can loop the array and populate my variables?
To import, you need an implementation of class QXmlDefaultHandler. In the example, that's class MyXmlHandler.

You could collect the date from the XML file in a member variable of your XML handler, for example:
function MyXmlHandler() {
    QXmlDefaultHandler.call(this);
    this.data = [];
}

MyXmlHandler.prototype = new QXmlDefaultHandler();

MyXmlHandler.prototype.startElement = function(namespaceURI, localName, qName, atts) {
    var attributes = {};
    for (var i=0; i<atts.length(); i++) {
        attributes[atts.localName(i)] = atts.value(i);
    }
    this.data.push([localName, attributes]);
    return true;
};
Then you can simple get the data from your caller class:
var xmlReader = new QXmlSimpleReader();
var source = new QXmlInputSource(file);
var handler = new MyXmlHandler();
xmlReader.setContentHandler(handler);
var ok = xmlReader.parse(source, false);
// do something with handler.data here...
// handler.data[index][0] is the tag name
// handler.data[index][1] is an object with the attributes
// e.g. 
// handler.data[index][1]["name"]
// handler.data[index][1]["measurement"]
// etc.
Note that this is not tested production code (there are likely errors) but the general idea will work.

wildspidee
Full Member
Posts: 84
Joined: Sat Nov 03, 2012 2:00 am

Re: XML Import Fails

Post by wildspidee » Fri Jan 23, 2015 6:42 pm

I was just testing and stumbled on part of the problem I was having yesterday. I was using your export xml file code when building mine. I copied it over "as-is" because that's the way I like to start, assuming it is correct before I start messing with it.

The problem is the comment -

Code: Select all

stream.writeComment("QCAD XML export example");
If you use the default I/O export and then try to import, it will fail. If you take this comment off, it works. I didn't pay any attention to the comment when I was testing and I think that was most of my problem.

Lori

wildspidee
Full Member
Posts: 84
Joined: Sat Nov 03, 2012 2:00 am

Re: XML Import Fails

Post by wildspidee » Fri Jan 23, 2015 7:32 pm

I got the XML export in the proper format. I've marked up the importer code with a switch statement for setting values on my variables. And now I'm completely lost.

The attached importer.js is basically just the body of your ExXmlImport.js with my switch. The FMBodice.js is my page that draws the pattern and it has the variables all set up at the top ready to hold the XML data. I have no idea how to get the importer code on the page. I gave it a try, but I really don't know how to do this.

This is the last piece of the process that I need to do. Can you help, please?
Attachments
importer.js
Import XML Code with Switch
(3.72 KiB) Downloaded 495 times
FMBodice.js
Drawing Instructions
(9.91 KiB) Downloaded 501 times
export3.xml
Export Created in QCAD
(765 Bytes) Downloaded 508 times

User avatar
andrew
Site Admin
Posts: 9037
Joined: Fri Mar 30, 2007 6:07 am

Re: XML Import Fails

Post by andrew » Mon Jan 26, 2015 11:38 am

You could include your importer.js in FMBodice.js:
include("importer.js");
Alternatively, you could have all in one file (FMBodice.js).

Note that you still have an action (i.e. separate tool) defined in importer.js (ExXmlImport). Since I think that FMBodice is your actual tool, that one you want to start to do all the work, you can get rid of the ExXmlImport class in importer.js and move the code from ExXmlImport.prototype.beginEvent over to FMBodice, for example to the beginning of FMBodice.prototype.beginEvent.

Post Reply

Return to “QCAD Programming, Script Programming and Contributing”