General XMetaL Discussion

XMetaL Community Forum General XMetaL Discussion Well-Formed Check In XMAX

  • scotth

    Well-Formed Check In XMAX

    Participants 1
    Replies 2
    Last Activity 10 years, 10 months ago

    Is there a way to programmatically check if an XML document is well-formed within XMAX? I am currently using the Validate method of the document object to ensure that a document validates against its schema. However, I have just realized that I am also going to need to do an additional check to ensure that the document is well-formed, meeting the XML specification. For example, I can insert a processing instruction with a name of “1234”, which does not meet the XML spec. Does XMAX have anything built in to check for this, or will I need to do it on my own?

    Reply

    Derek Read

    Reply to: Well-Formed Check In XMAX

    There is an API for checking that XMAX is running in “well formed editing mode” but I don't think that is what you are looking for. Generally, for XMAX to open a file in that mode you must specifically tell it to do so when calling LoadFromString or LoadFromFile.

    A document must be well-formed as a prerequisite for it to be valid, so doing an additional check to see that it is well-formed would not give you any further information.

    I see that a processing instruction with a target of “1234” is being allowed by XMAX (ie: no validation error is added to the ValidationErrorList property). That is incorrect according to the XML Recommendation, which states that the target is supposed to be a “name” and names do not allow digits (0-9) as the first character (among many other restrictions). I assume that is what you are really getting at.

    I will log a bug with development for this.

    In the meantime you could do a specific scripting check to validate PI targets yourself. The simplest way to do that may be using a regular expression in JScript. Coming up with the right regular expression is likely the hard part. To obtain the value of a PI target you can use the API DOMProcessingInstruction.target.

    If this is truly a show stopper for you and you need some kind of immediate solution, I could try to write such a script. Let me know.

    Reply

    Derek Read

    Reply to: Well-Formed Check In XMAX

    OK, I would suggest using a function similar to the following. You could call it from any code you have in place for XMAX that is displaying validation errors and add your own messaging (I have provided some suggestions, though you might also just simplify to something like “your PI target is bad”).

    Code for locating the PIs (and their target values) in your document is not provided here as that should be simple to figure out I think.

    This function returns a value indicating the “validity” of a particular name as a number value 0-3 where 0 means “valid” and the other three values have slightly different meanings (while they all also mean “invalid”).

    The specific rules for PIs are defined here: http://www.w3.org/TR/REC-xml/#sec-pi
    My code has adapted the definitions for the character groups that are allowed in the XML Recommendation and turned those into JScript regular expressions to make it easy to match those up and confirm that the right characters are in fact being looked for.

    [code]//XMetaL Script Language JScript:
    function isValidName(nameStr) {
    if (nameStr.substr(0,3).toUpperCase() != “XML”) {
    //name doesn't begin with “XML” (case insensitive), continue…
    var NameStartCharRE=/([:]|[A-Z]|[_]|[a-z]|[u00C0-u00D6]|[u00D8-u00F6]|[u00F8-u02FF]|[u0370-u037D]|[u037F-u1FFF]|[u200C-u200D]|[u2070-u218F]|[u2C00-u2FEF]|[u3001-uD7FF]|[uF900-uFDCF]|[uFDF0-uFFFD])/;
    if (nameStr.charAt(0).search(NameStartCharRE) == 0) {
    //first character is OK, continue to check the rest…
    var NameCharRE = /([:]|[A-Z]|[_]|[a-z]|[u00C0-u00D6]|[u00D8-u00F6]|[u00F8-u02FF]|[u0370-u037D]|[u037F-u1FFF]|[u200C-u200D]|[u2070-u218F]|[u2C00-u2FEF]|[u3001-uD7FF]|[uF900-uFDCF]|[uFDF0-uFFFD]|[-]|(.)|[0-9]|[u00B7]|[u0300-u036F]|[u203F-u2040])/;
    for(i=0;i if(nameStr.charAt(i).search(NameCharRE) == -1) {
    return 1; // target contains an illegal character
    }
    }
    //we got through every character without error…
    return 0; // target is a valid name
    }
    else {
    return 2; // target begins with an illegal character
    }
    }
    else {
    return 3; // target must not begin with the string 'xml', or with any string which would match ((X|x) (M|m) (L|l))
    }
    }[/code]

    Call the following (after defining the function above elsewhere in your code).
    These tests simply pass in various strings to test as target names to confirm that my function is testing properly.

    [code]//Following should return 2: target begins with an illegal character
    var name = “1234”;
    var response = isValidName(name);
    ActiveDocument.Host.Alert(“target = ” + name + “nn” + response);

    //Following should return 3: target must not begin with the string 'xml'
    var name = “XmL1234”;
    var response = isValidName(name);
    ActiveDocument.Host.Alert(“target = ” + name + “nn” + response);

    //Following should return 0: target is valid
    var name = “_1234”;
    var response = isValidName(name);
    ActiveDocument.Host.Alert(“target = ” + name + “nn” + response);

    //Following should return 0: target is valid
    var name = “_1234.asdf”;
    var response = isValidName(name);
    ActiveDocument.Host.Alert(“target = ” + name + “nn” + response);

    //Following should return 0: target is valid
    var name = “:1234”;
    var response = isValidName(name);
    ActiveDocument.Host.Alert(“target = ” + name + “nn” + response);

    //Following should return 0: target is valid
    var name = “a1234”;
    var response = isValidName(name);
    ActiveDocument.Host.Alert(“target = ” + name + “nn” + response);

    //Following should return 1: target contains an illegal character
    //Note that the last character in this string is a 'GREEK QUESTION MARK' (it may look like a standard semicolon).
    //If the forum software or database does not properly preserve this character note that it is U+037E if you wish to run this test.
    var name = “a1234Íž”;
    var response = isValidName(name);
    ActiveDocument.Host.Alert(“target = ” + name + “nn” + response);[/code]

    Reply

  • You must be logged in to reply to this topic.

Lost Your Password?

Products
Downloads
Support