Author |
Message
|
catshout |
Posted: Thu Feb 19, 2015 4:10 am Post subject: Special chars (German Umlaute) in Saxon XSLT transformation |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
I'm currently setup a flow that uses SaxonHE 9 library to transform a XML payload with XSLT 2.0.
The transformation at all works but some special chars are not translated in a right manner, e.g. "ß"; "Fuß" becomes "Fuß".
Seems to be a codepage issue. The message itself does contain CCSID 1208.
See below the code snippet from the Java Compute node ..
Code: |
MbElement srcPayload = outMessage.getRootElement().getLastChild().getFirstChild();
byte[] messageBody = (byte[]) MbMessageUtil.getByteStreamFromXMLNSCElement(srcPayload);
String xmlIn = "<?xml version=\"1.0\" encoding='UTF-8'?>" + new String(messageBody);
// Setup output stream
ByteArrayOutputStream xmlOut = new ByteArrayOutputStream();
// Setup input stream
StreamSource xmlSrc = new StreamSource(new StringReader(xmlIn));
Processor proc = new Processor(false);
XsltCompiler comp = proc.newXsltCompiler();
XsltExecutable exp = comp.compile(new StreamSource(new File("F:\\var\\mqsi\\XSLT\\transform.xslt")));
XdmNode source = proc.newDocumentBuilder().build(xmlSrc);
Serializer ser = proc.newSerializer(xmlOut);
XsltTransformer trans = exp.load();
trans.setInitialContextNode(source);
trans.setDestination(ser);
trans.transform();
// Result processing
outMessage.getRootElement().getLastChild().delete();
MbMessageUtil.addBlobPayLoad(outMessage, xmlOut.toByteArray(), "BLOB");
|
After the Java Compute node follows a RCD node to parse the BLOB into a XML.
Same transformation with SaxonHE 9 on command line on the same server works fine.
Any ideas or hints are highly appreciated. |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Feb 19, 2015 5:51 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Completely wrong approach. Either use an XSLT node, or a mapping node but please use the broker's parser.
Just because you can use the broker in this way does not mean you should.
If your purpose was to add the xml declaration to the message, did you even look at the infocenter on how to do that in java???
You're going at it completely the wrong way. You should also set the CCSID to match your xml declaration...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
Vitor |
Posted: Thu Feb 19, 2015 6:46 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
fjb_saper wrote: |
Completely wrong approach. Either use an XSLT node, or a mapping node but please use the broker's parser. |
You're reinventing the wheel, and yours is not entirely circular.
catshout wrote: |
Same transformation with SaxonHE 9 on command line on the same server works fine. |
Yes, and if the broker was opening a command prompt and typing the command it would probably work.
It's not the same environment.
That's why there's an XSLT node. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
catshout |
Posted: Thu Feb 19, 2015 7:03 am Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Thanks for the reply.
The reason for not using XSLT node or Mapping node is that the XSLT has been created by another tool and requires XSLT 2.0 (as described). XSLT 2.0 isn't supported yet in IIB 9 as I know.
So far Saxon seems to be a way to process a XSLT 2.0 transformation. Do you see another option?
Yes, adding the XML spec isn't the smart way .. I'm just focussing on the XSLT 2.0 part to find the right approach. And yes, the message CCSID is matching with xml declaration. |
|
Back to top |
|
 |
mqjeff |
Posted: Thu Feb 19, 2015 7:07 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Did you tell toByteArray() what CCSID to produce the blob in?
Does your addBlobPayLoad() do the right thing with the CCSID of the blob data, including setting the necessary parts of the message tree to indicate the correct CCSID? |
|
Back to top |
|
 |
catshout |
Posted: Thu Feb 19, 2015 7:27 am Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Thanks, mqjeff.
The "addBlobPayLoad" method finally calls the "createElementAsLastChildFromBitstream" method with the appropriate CCSID (always 1208).
The prior method call "toByteArray()" just converts a byte stream into a byte array. There's no further parameter.
The message CCSID will always remain at 1208 over time. |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Feb 19, 2015 9:09 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
catshout wrote: |
The prior method call "toByteArray()" just converts a byte stream into a byte array. There's no further parameter. |
This is where the crux is. I know the mantra: A byte array is a byte array is a byte array... Only this is not quite true... it all depends on how the byte stream was created... especially if the source was text!!!
And you did not give us information on how you coded
Code: |
byte [] MbMessageUtil.getByteStreamFromXMLNSCElement(MbElement srcPayload)
or maybe
Object MbMessageUtil.getByteStreamFromXMLNSCElement(MbElement srcPayload)
as you did see fit to cast to byte[]... |
 _________________ MQ & Broker admin |
|
Back to top |
|
 |
catshout |
Posted: Thu Feb 19, 2015 10:28 am Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Quote: |
And you did not give us information on how you coded |
This is the method being called in detail
Code: |
public static byte[] getByteStreamFromXMLNSCElement(MbElement element) throws MbException {
MbElement tmpElement = element.copy();
MbMessage tmpMessage = new MbMessage();
byte[] byteStream = null;
tmpMessage.getRootElement().createElementAsLastChild(MbXMLNSC.PARSER_NAME);
tmpMessage.getRootElement().getLastChild().addAsLastChild(tmpElement);
byteStream = tmpMessage.getRootElement().toBitstream(null, null, null, 0, 1208, 0);
return byteStream;
} |
|
|
Back to top |
|
 |
rekarm01 |
Posted: Thu Feb 19, 2015 8:43 pm Post subject: Re: Special chars (German Umlaute) in Saxon XSLT transformat |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 1415
|
Using both single and double quote characters in the XML declaration is not the best practice:
catshout wrote: |
Code: |
String xmlIn = "<?xml version=\"1.0\" encoding='UTF-8'?>" + new String(messageBody); |
|
When converting a byte[] to String, how does the String() constructor know the bytes are supposed to be a UTF-8, rather than the platform default charset?
Check the Java API for more suitable constructors. |
|
Back to top |
|
 |
fjb_saper |
Posted: Fri Feb 20, 2015 9:01 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
catshout wrote: |
Quote: |
And you did not give us information on how you coded |
This is the method being called in detail
Code: |
public static byte[] getByteStreamFromXMLNSCElement(MbElement element) throws MbException {
MbElement tmpElement = element.copy();
MbMessage tmpMessage = new MbMessage();
byte[] byteStream = null;
tmpMessage.getRootElement().createElementAsLastChild(MbXMLNSC.PARSER_NAME);
tmpMessage.getRootElement().getLastChild().addAsLastChild(tmpElement);
byteStream = tmpMessage.getRootElement().toBitstream(null, null, null, 0, 1208, 0);
return byteStream;
} |
|
From your code it seems that your purpose is to add an XML declaration to the message... so which part of
Quote: |
If your purpose was to add the xml declaration to the message, did you even look at the infocenter on how to do that in java??? |
did you not understand??
Also when creating a new message and not copying the headers, you better check the properties.CodedCharSetID... it might not be what you expect...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
|