Pages: 1
Print
Author Topic: Xmetal hangs/crashes on ActiveDocument.Reload()  (Read 4584 times)
gcrews
Member

Posts: 265


« on: January 26, 2013, 03:48:15 PM »

XMetaL(R) Author Enterprise 7.0
Version#: 7.0.0.111

I am trying to use use  ActiveDocument.Reload() in a macro for XHTML files. XHTML files open normally fine, but when I call Reload(), XmetaL hangs and has to be force closed.

From what I can tell, it looks like when Reload() is called, it is trying to load the xhtml1-transitional.dtd from w3.org instead of using the catalog entries i have created.

C:\Program Files\XMetaL 7.0\Author\Rules\catalog

   PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "xhtml/xhtml1-strict.dtd"
   PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "xhtml/xhtml1-frameset.dtd"
   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "xhtml/xhtml1-transitional.dtd"
   PUBLIC "-//W3C//ENTITIES Latin 1 for XHTML//EN" "xhtml/xhtml-lat1.ent"
   PUBLIC "-//W3C//ENTITIES Symbols for XHTML//EN" "xhtml/xhtml-symbol.ent"
   PUBLIC "-//W3C//ENTITIES Special for XHTML//EN" "xhtml/xhtml-special.ent"
« Last Edit: January 26, 2013, 04:43:58 PM by gcrews » Logged
gcrews
Member

Posts: 265


« Reply #1 on: January 28, 2013, 03:04:54 PM »

Update:
          After much hunting, I found how DocBook adds its catalog.xml in xmetalSamples.mcr. Looks like to correctly setup XMetaL with customized catalog entries you have to make a Javascript call and have a catalog xml file.  It seems XMetaL doesn’t fully use the entries to the Rules\catalog file for all resolving.
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #2 on: January 29, 2013, 03:29:44 PM »

I assume your DOCTYPE decl looks something like the following (as recommended by W3C for use on the web):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Catalog files work as you would expect in XMetaL Author (and as documented) and don't require any special code to be created for normal use. However, in this case they never come into play because the SYSTEM id value above points to a DTD that is present (the W3C actually hosts a copy there) and so XMetaL 'helpfully' downloads it for you and uses that copy. In cases where a company owns that location they can put a CSS, CTM and MCR file with the same name as the DTD there (or an XAC file) and XMetaL will download and use them, giving you a fully functioning XMetaL customization. I wouldn't generally recommend it (for reasons including the fact that it might be slow and adds the complexity of managing a web server) but the feature exists for that reason. It works the same for XSD files.

The PUBLIC id value is only used when XMetaL determines that there is no file located at the path specified in the SYSTEM id (the second quoted section in the DOCTYPE decl). The diagram on page 8 in this set of slides shows the logic: http://www.slideshare.net/XMetaL/deploying-schemas-and-xmetal-customization-files

XMetaL will probably wait forever for the DTD to arrive as long as it has been told (in this case by the W3.org server) that it is going to get something. If the server doesn't offer it up or it takes a long time to do so that could look like the software is frozen. It is up to the W3.org website in this case. After downloading, the file will be placed in your Windows account's "temp" folder somewhere similar to the following (if you look at "temp" you will see lots of junk in there from many different apps):
C:\Documents and Settings\<windows login>\Local Settings\Temp\<random number>\www.w3.org\TR\xhtml1\DTD\

To find the exact location of the DTD after download you can use this API:
//XMetaL Script Language JScript:
Application.Alert(ActiveDocument.RulesFile);


Right now it looks like it takes between 5 and 10 minutes for the W3.org website to serve up this DTD when requested (tested with both XMetaL and several different web browsers). Keep in mind that there are 4 files involved (the DTD and 3 ENT files that it references).

Having said all of that, I'm not sure about ActiveDocument.Reload() and any crashes you are seeing. However, calling that API causes XMetaL to reload the XML file from disk, and the whole process is pretty much identical to you closing the file and then reopening it, except that in this can the API doesn't care if the file has not been saved or if any changes were made to it, those are all just thrown away. The whole document is validated upon opening however, and customization files should be reloaded. I doubt that API has ever been stress tested to any degree, and it may not really be designed to work with DTDs not located on your local system (not sure).

It sounds like your real issue is that you want XMetaL to use your local copy of the DTD. Anyone customizing XMetaL really doesn't want their DTD to be downloaded from a server they have no control over and have a customization be autogenerated. You want to control which DTD is being used so you can specify your own CSS, CTM and possibly MCR code.

The easiest thing to do in this case is to change the DOCTYPE declaration. In most cases the XML file you are editing with XMetaL is not in its final form and almost always needs to be transformed to some other format for final consumption. XHTML is a special case because it can be used as the final format so changing the DOCTYPE might seem like adding some unecessary complexity to things, however, it is really the browser (or W3C) that wants the DOCTYPE in that final format. One simple change to the file as an XSLT transform would do that. The alternative would be to add a "Save for Web" macro that would take ActiveDocument.Xml and append it to the desired <DOCTYPE> and maybe even remove the XML declaration. That would be a very simple script to write but you'd probably need to use FSO to write out the file since XMetaL's own APIs won't let you mess with the DOCTYPE or remove the XML declaration.

The alternative would be to leave the XML declaration alone but get XMetaL to use your local copy of the DTD. An application-level macro should let you do that. Something like this:

<MACRO name="On_Application_Resolve_Entity" lang="JScript" hide="true"><![CDATA[
Application.Alert(Application.ResolveEntityInfo.systemID);
if (Application.ResolveEntityInfo.systemID == "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd") {
   Application.ResolveEntityInfo.systemID = "C:\\my_xmetal_customizations\\xhtml\\xhtml1-strict.dtd";
}
Application.Alert(Application.ResolveEntityInfo.systemID);
]]></MACRO>
Logged
gcrews
Member

Posts: 265


« Reply #3 on: January 30, 2013, 12:40:48 AM »

frozen/hang/crash/Not responding, there all the same to me if an application GUI is not responding for over 5 min. How am I supposed to know its waiting on a web request? After 20 seconds any user is going to consider an application any of those terms.

I see now that XmetaL was going out to w3.org every time I open a xhtml document and creating temp folders. There were over 2000 of those #### folders with no files in them, just some w3.org sub folders cluttering up my temp folder. Initially, xMetaL would frozen while waiting for w3.org when opening xhtml files. After adding the xhtml entries in the Rules\catalog file they opened fine with no delay. I see now though, it was still making http requests out to w3.org but was not waiting for a response and used the \catalog entries instead. For some reason the Reload() function seems to force xMetaL to wait on w3.org again.

Since I saw the HTML entries in the catalog file, I thought that's all that had to be changed to resolve them locally. I was looking though the information in the Mapping identifiers section of the Customization Guide. Sounds like On_Application_Resolve_Entity is what I need to create a macro for to resolve them to locally stored files. I will give that a try. I would have never thought there was a macro related to the resolving, all i was looking for was catalog related information. 

What about using the addCatalog() function in the XML Catalog Resolver service the way that xmetalSamples.mcr adds a catalog.xml file around line 300?  That seems to work well and the entries are nicely defined in an xml file instead of hard coding them into if statements.  

PS: I know why w3.org takes a long time to respond, because w3.org gets  way to many requests for those files and they intentionally make it take a very long time. At minimum it should cache them, not re-request them on every document  and changing views. You might want to take a look at this article from a few years ago:
  http://www.w3.org/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic/

Thanks for the detailed information and suggestions.  
« Last Edit: January 30, 2013, 01:36:44 AM by gcrews » Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #4 on: January 31, 2013, 01:11:42 PM »

I can't recommend the addCatalog() function as that is currently meant for internal use. However, if it works in your testing then the only thing you would likely need to worry about is that we might change its behaviour with any future release. It is unlikely to change that much, but as it is not an API there is nothing stopping one of our developers from rewriting it.
Logged
Pages: 1
Print
Jump to:  

email us