XML Parsing and XSLT Issues

599 views
Skip to first unread message

Brian

unread,
Feb 25, 2016, 11:10:34 AM2/25/16
to Caché, Ensemble, DeepSee
We have been seeing multiple issues witht he SAX Parser and with the TransformStreamWithCompiledXSL methods in the XML.XSLT>Transformer class.

Sample XML:

<ns1:QUQI_IN444211QD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="urn:hl7-org:v3" ITSVersion="XML_1.0"><ns1:id e
xtension="541970483"/></ns1:QUQI_IN444211QD>

I run the following commands:

Set IncomingStream = ##Class(%FileCharacterStream).%New()
Do IncomingStream.Write(IncomingRequest)
do IncomingStream.Rewind()
Set writer = ##Class(%XML.Writer).%New()
Set writer.Charset="UTF-8"
Do writer.OutputToStream(.NewStream)
Set Resolver = ##Class(%XML.SAX.EntityResolver).%New()

Do ##class(%XML.TextReader).ParseStream(IncomingStream ,.reader, Resolver, 31)

Is adding: <?xml version="1.0" encoding="UTF-8"?>_$C(13,10)  to the Beginning of my XML? Any idea on what flags I can send through to stop this?

After removing this line from my stream, I pass this stream to:

Set status = ##class(%XML.XSLT.Transformer).TransformStreamWithCompiledXSL(NewStream, gObjXsl, .StreamObj)).

This Method is choking on the following:
<ns1:QUQI_IN444211QD> (The preceding ns1 tag).

This is "Valid" XML? Why is cache choking on this? (FYI: If I remove the ns1:, it works fine)


Any help would be Greatly appreciated!!!!



Brian

unread,
Feb 25, 2016, 2:13:14 PM2/25/16
to Caché, Ensemble, DeepSee
The issue:


Is adding: <?xml version="1.0" encoding="UTF-8"?>_$C(13,10)  to the Beginning of my XML? Any idea on what flags I can send through to stop this?

Is no longer an issue.  The Transform is handling it properly.

But I still have the issue:  <ns1:QUQI_IN444211QD> (The preceding ns1 tag).


This is "Valid" XML? Why is cache choking on this? (FYI: If I remove the ns1:, it works fine)

Kevin Mayfield

unread,
Feb 25, 2016, 3:19:54 PM2/25/16
to Caché, Ensemble, DeepSee
I've had the same problem and handled the same way.

Suspect it's the way Caché calls the processor.

Brian

unread,
Feb 25, 2016, 3:36:15 PM2/25/16
to Caché, Ensemble, DeepSee
I haven't found a solution to the 2nd problem?   Did you have that problem?  If so, how did you resolve it?

My guess is that Cache calls out to C++ and uses the XALAN processor.  XALAN will process the preceeding namespace in the root node, not sure why Cache won't?

Thanks!!!!!

Dmitry Maslennikov

unread,
Feb 26, 2016, 2:57:56 AM2/26/16
to Caché, Ensemble, DeepSee
Unfortunately it is difficult to understand whats wrong in your code, because your code, fragmented, almost every line completely not connected to other.

    Set IncomingStream = ##Class(%FileCharacterStream).%New()
    Do IncomingStream.Write(IncomingRequest)
    do IncomingStream.Rewind()
here you create some stream, let's think it contains XML in HL7v3 format
    Set writer = ##Class(%XML.Writer).%New()
    Set writer.Charset="UTF-8"
    Do writer.OutputToStream(.NewStream)
looks useless code, why you showed it ?
    Set Resolver = ##Class(%XML.SAX.EntityResolver).%New()

    Do ##class(%XML.TextReader).ParseStream(IncomingStream ,.reader, Resolver, 31)
and finally you says, that code 
Is adding: <?xml version="1.0" encoding="UTF-8"?>_$C(13,10)  to the Beginning of my XML
hmm, what code ? parser ?, it is just parse XML, it can't add any xml header. %XML.Writer may add it, and yes it add it by default, and you can off it.
   Set writer.NoXMLDeclaration=1

and here you got an error
  Set status = ##class(%XML.XSLT.Transformer).TransformStreamWithCompiledXSL(NewStream, gObjXsl, .StreamObj)
Ok, how we can decide what appeared in NewStream in gObjXsl ?

If you show working example, with all data, XML and XSLT, we may help.

Now I can only suggest that you somewhere missed namespace declaration.



--
--
Caché, Ensemble, DeepSee

---
You received this message because you are subscribed to the Google Groups "Caché, Ensemble, DeepSee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to intersystems-publi...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Dmitry Maslennikov
Lead Programmer at LETOGRAF
Skype: DAiMor

Brian

unread,
Feb 26, 2016, 10:12:06 AM2/26/16
to Caché, Ensemble, DeepSee
Thanks Dmitry for your Respose,   Here is a little update:

IncomingRequest = <ns1:QUQI_IN444211QD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="urn:hl7-org:v3" ITSVersion="XML_1.0"><ns1:id e

xtension="541970483"/></ns1:QUQI_IN444211QD>

    Set IncomingStream = ##Class(%FileCharacterStream).%New()
    Do IncomingStream.Write(IncomingRequest)
    do IncomingStream.Rewind()

The call to the Resolver was irrelevant, I was testing some other things.  So the call is:

Do ##class(%XML.TextReader).ParseStream(IncomingStream ,.reader, "", 31)

And yes, ParseStream does add The <?xml> tag when you tell it to process Namespaces (See %occSAX, this include defines the bit flags used by the Reader).  In the example above i'm using 31.  Which is 27 (the default) and I'm adding 4 to include parsing of the namespaces:

Documentation from %occSAX.inc
#; http://xml.org/sax/features/namespace-prefixes
#; On: Report the original prefixed names and attributes used for Namespace declarations
#; Off: Do not report attributes used for Namespace declarations, and optionally do not report original prefixed names (default)
 
#define SAXNAMESPACEPREFIXES            4

When this Bit is defined, the ParseStream Function which uses %XML.SAX.Parser will process the xmlns tags in your document and in fact adds the <?xm> tag.

Like I said couple posts back, this is not the issue (And your suggestion of  Set writer.NoXMLDeclaration=1 Worked to remove the <?xml> tag, Thanks!!!)

I was trying to keep it short and didn't include all the code. Sorry abou that!!

// external xslt
Set XSLFile = TransObj.XSLINName
// compile style sheet
Set gObjXsl = ""
Set status = ##class(%XML.XSLT.CompiledStyleSheet).CreateFromFile(XSLFile, .gObjXsl)
// Transform
Set StreamObj = ##class(%GlobalCharacterStream).%New()

Set status = ##class(%XML.XSLT.Transformer).TransformStreamWithCompiledXSL(NewStream, gObjXsl, .StreamObj)

Set ConvertedObj = ##class(QLS.SYS.XML.Input).ConvertStreamToObject(StreamObj, TransObj.ClassName, TransObj.MsgName)

The above function does:
    // Create a new XML Reader class
    Set ReaderObject = ##class(%XML.Reader).%New()

    // Begin processing of the XML input
    Set sc=ReaderObject.OpenStream(Stream)
    If $$$ISERR(sc) G Error

    Do ReaderObject.Correlate(XMLTagName , Class)
   
    S st=ReaderObject.Next(.OutObject,.Status)
    If st{
        Quit OutObject
    }

I get the following error in %objlasterror

ERROR #6301: SAX XML Parser Error: Invalid document structure while processing Anonymous Stream at line 1 offset 45

So, from my original Post.  If I remove the preceeding ns1: in the V3 (IncomingRequest), the object will convert correctly.


THANKS AGAIN!!!
To unsubscribe from this group and stop receiving emails from it, send an email to intersystems-public-cache+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Dmitry Maslennikov

unread,
Feb 26, 2016, 11:54:06 AM2/26/16
to Caché, Ensemble, DeepSee
Thanks for clarifications, but I still not sure in what code you got error.
is it in %XSLT.Transformer or In %XML.Reader
If in XSLT, so, it would be better if you can send xml and xslt, and I would check it by myself

To unsubscribe from this group and stop receiving emails from it, send an email to intersystems-publi...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--
Dmitry Maslennikov
Lead Programmer at LETOGRAF
Skype: DAiMor

--
--
Caché, Ensemble, DeepSee

---
You received this message because you are subscribed to the Google Groups "Caché, Ensemble, DeepSee" group.
To unsubscribe from this group and stop receiving emails from it, send an email to intersystems-publi...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages