Skip to main content
1-Visitor
June 7, 2013
Question

auto assign a pubid in xml files without a doctype declaration

  • June 7, 2013
  • 7 replies
  • 1605 views

Hello members,



I´ve got xml files that don´t have a doctype declaration and I can´t add this because of workflow reasons.



Can I tell the Arbortext Editor to assign a specific pubid, when the xml file loaded has a specific root element? The solution should be placed in the custom directory, I can´t get access to the rest of the installation directory because of rights permission.



Thanks in advance
Thomas

    7 replies

    1-Visitor
    June 7, 2013
    You can do this with a "doctype" entry in your catalog. Try searching for
    an article titled "Catalog files" in the Help Center.

    -Brandon 🙂


    18-Opal
    June 7, 2013
    Hi Brandon--

    Do you have a working example of this? I can get it to work if there is a DOCTYPE declaration in the file with no public or system ID, e.g.



    But I can't get it to work if there is no DOCTYPE declaration at all, which I think is Thomas's situation (if I read his original post correctly).

    As for a solution, I was thinking along the lines of a script in editinit that checked the root element's name, and reopened the document with the desired doctype if it matched as certain name. But that's just theoretical, I haven't tested it.

    --Clay
    1-Visitor
    June 7, 2013
    Clay,



    I think that is what Thomas is saying, he has no DOCTYPE declaration. When I
    was more involved with Epic, the company I worked for had the same problem,
    but it was taken care of by the database management application. It would
    strip everything before the root element of the file (which was not always
    the root element of the DOCTYPE).



    I am wondering if there might not be a way to capture the file opening event
    and then programmatically find the root element (e.g., oid_first_tag() help
    988) then assign a DOCTYPE based on that element. This does have some
    pitfalls if there are several DOCTYPEs in use and there are common elements
    between them.

    Another approach might be to find the path of the file being opened. If it
    is consistent and all files for a given doctype are in the same folder, you
    could again add the DOCTYPE declaration.



    Lynn


    18-Opal
    June 7, 2013
    Hi Lynn--

    Right, that's what I was thinking, too. A quick experiment shows that it works to put something like this in your editinit.acl file:

    # check root element and reload using doctype

    if ((oid_name(oid_root())=="foo") && (doc_freeform())) {
    $doc = current_doc();
    $path = doc_path($doc);
    # close the version initially opened as freeform
    doc_close($doc);
    # reopen, forcing the desired doctype (0x40 flag)
    $newdoc = doc_open($path, 0x40, ", ", $APTCUSTOM . "/doctypes/foo/foo.dtd");
    # load the new doc in the edit window
    doc_show($newdoc, current_window());
    }

    Of course, replace "foo" and "/doctypes/foo/foo.dtd" with more appropriate values. If you had several top-level elements you wanted to handle this way, it wouldn't be hard to set up an associative array that would map root element names to doctype paths.

    --Clay
    5-Regular Member
    June 7, 2013
    Hi,

    I've done something similar recently. I was using a callback function, placing something like this in a init.acl in the "custom/init" folder:
    doc_add_callback(0, "create", "mypackage::open_freeform_doc");

    This callback is fired each time a new document window is created so make sure to have an early check if you want to do anything in your callback function "open_freeform_doc".

    That function would be pretty much the same what Clay showed before. What I did do cope with different doctypes: I created an associative array using the root element as key and the PUBLICID of the corresponding doctype as value. So in my callback function I can retrieve the root element and lookup the doctype in my global array (here DOCTYPES) like this:
    local roottag = oid_name(oid_root(theDoc));
    local doctype = DOCTYPES[roottag];

    To get back to Clays example, instead of using the actual location of the dtd file you could also give the PUBLICID to the doc_open function. Be aware that you need to have your catalog files setup correctly so that Arbortext can resolve the PUBLICID to the actual DTD.

    I hope that makes sense...

    Kind regards

    Sirko
    1-Visitor
    June 10, 2013
    Hi, Clay...

    You got me. 🙂 I sent that suggestion off the cuff, based on my
    recollections that, somewhere in the past, I had gotten a tool which
    supported SGML catalogs (probably SP or Jade) to work with DOCTYPE entries.
    Seeing it mentioned in the help center made me relatively confident it
    would work, but I had not taken the time to confirm it.

    I like the purely declarative solution of using a DOCTYPE entry in the
    catalog, but in lieu of proper support from Editor, your ACL solution would
    be my next choice. Extra credit, though, for Sirko's tweak of using the
    Public ID to let the catalogs do their thing, thus avoiding path-fiddling
    headaches, such as cases where APTCUSTOM contains a list of paths, rather
    than just one. Better yet might be to use the catalog_resolve function to
    look up a DOCTYPE entry for the root element, so the mapping from element
    name to Public ID could be maintained in the catalog, rather than in ACL
    code.

    Off hand, I'd say it's a toss-up whether it's better to put the code in an
    editinit script or a document create callback. The latter is a bit more
    work and I can't think of a case it'd catch that the former wouldn't, but
    Editor hasn't been occupying my aging brain much, lately. 😛

    -Brandon 🙂


    1-Visitor
    June 10, 2013

    Hi all,



    That´s exactly what I need. I´ve implemented a combination from Sirko´s and Clay´s suggestions and it works fine. So I´d like to thank you pretty much for your helpful answers.



    Best,
    Thomas