okay, so I've got a thing that's weird. <https://t...
# adobe
t
If I parse the xml with the schema, it throws an error. But then if I parse it without the schema, and validate it against the schema instead, then it's successful. Anyone know why?
d
If you add the
lenient
argument as
true
it works: https://trycf.com/gist/14d7da559d718dd04577e456d4901df2/lucee5?theme=monokai I'm guessing that XmlValidate() is "lenient" by default. I know the XmlParse() was recently updated to make it "secure" by default now, so this might have been part of the change.
r
We do some XML parsing/validation in one of our apps, and use an XMLParse() call similar to the first one including the schema. The XML files we're processing include the starting `<?xml...>`tag and the root element references the same schema as part of the XML namespace for the file. We parse-with-schema and if that fails, we catch the exception and use XMLValidate() to get a list of the schema validation failures.
(hmmm... deleted my response from a minute ago...)
OK, let's try this again: riffing on your gist, our code looks more like this:
Copy code
<cfscript>
    sampleXML = '<?xml version="1.0" encoding="UTF-8"?><x:response xmlns:x="<https://demo.sunapsis.iu.edu/ioffice/xml/schema/sunapsis/datalayer>" xmlns:xsi="<http://www.w3.org/2001/XMLSchema>" xsi:schemaLocation="<https://demo.sunapsis.iu.edu/ioffice/xml/schema/sunapsis/datalayer.xsd>"><header><success>false</success><responseInfo/><id>0</id></header><dataset type="null"/></x:response>';
    
    cfhttp(url = "<https://demo.sunapsis.iu.edu/ioffice/xml/schema/sunapsis/datalayer.xsd>", method = "get", result="schema");
    
    try {
        xmlObj = XmlParse(sampleXML, true, schema);
    }
    catch( any error ) {
        WriteDump(error);
        xmlObj = XmlParse(sampleXML, true);
        validation = XmlValidate(xmlObj, schema);
        WriteDump(validation);
    }
</cfscript>
... although we use a local XSD and
schema
in the call in our code points to the file on the local filesystem where the above retrieves the schema and then passes it into the XMLParse() call. There's something weird going on with the XMLParse() function's ability to actually get the schema it needs and having the schema either locally or in a variable passed into that first XMLParse() call avoids that weirdness. This brings back lots of bad memories, BTW.
... and this also works:
Copy code
<cfscript>
    sampleXML = '<response><header><success>false</success><responseInfo/><id>0</id></header><dataset type="null"/></response>';
    
    cfhttp(url = "<https://demo.sunapsis.iu.edu/ioffice/xml/schema/sunapsis/datalayer.xsd>", method = "get", result="schema");
    
    try {
        xmlObj = XmlParse(sampleXML, true, schema);
    }
    catch( any error ) {
        WriteDump(error);
        xmlObj = XmlParse(sampleXML, true);
        validation = XmlValidate(xmlObj, schema);
        WriteDump(validation);
    }
</cfscript>
... and goes back to your original XML, but just pulls the schema into a local variable.
t
Will take a closer look at these in the morning, but thanks for the ideas.
@rstewart So, in my actual code, I am using a local path to the schema. I just used the URL for the gist, thinking it wouldn't matter. And upon further reflection, I think it doesn't... I think passing the cfhttp result to XmlParse just results in the schema parameter being ignored because it's not valid. If I change it to
XmlParse(sampleXML, true, schema.fileContent)
so i actually have the schema string instead of a cfhttp struct then it starts failing again with the same message as passing a URL or a path. If I add in the prolog and the namespace/schema declarations then it does work. So I think the
lenient
idea is correct. But it looks like that param is Lucee only.
r
RE schema.fileContent: ugh. duh. I missed that.