Enlib.EDI.XML.Document to XSLT Stylesheet
I am trying to transform an Enlib.EDI.XML.Document through aXLT I know how to trans form the xml document through a xlt stylesheet but been trying to get an Enlib.EDI.XML. Document from a procees by creating aoperation that will do the transformation of this to file if this can be done in a process all ideas welcome so far I have come to this and I keep getting an error
:ERROR{ERROR #5002: Cache error: <PROPERTY DOES NOT EXIST>zXMLTOJson+6^TestEnvironment.Custom.GENERAL.CUSTOM.XLT.XMLToJsonOperation1.1 *Parameters,EnsLib.EDI.XML}Class XLT.XMLToJsonOperation1 Extends (Ens.BusinessOperation, EnsLib.XSLT.Transformer)
{ Parameter ADAPTER = "EnsLib.File.OutboundAdapter"; Property Adapter As EnsLib.File.OutboundAdapter; /// Style sheet to convert Message to Json
Property XLTStyleSheet As %String(MAXLEN = ""); Parameter SETTINGS = "XLTStyleSheet:Basic"; Parameter INVOCATION = "Queue"; /// Default operation is to use a TransformationRequest to transform the input XML into the output
Method XMLTOJson(pRequest As EnsLib.EDI.XML.Document, Output pResponse As EnsLib.XSLT.TransformationResponse) As %Status
{
Set tSC=$$$OK,$ZT="Trap"
do {
// Grab the input content and the stylesheet key
Set tInput = pRequest
Set tSSKey = ..XLTStyleSheet
Set tSC = ..Transform(tInput,tSSKey,pRequest.Parameters,.tOutput)
If $$$ISOK(tSC) {
Set pResponse = ##class(EnsLib.XSLT.TransformationResponse).%New()
Set pResponse.Content = tOutput
}
} while (0)
Exit Quit tSC
Trap Set tSC=$$$ERROR($$$CacheError,$ZE) Goto Exit
} XData MessageMap
{
<MapItems>
<MapItem MessageType="EnsLib.EDI.XML.Document">
<Method>XMLTOJson</Method>
</MapItem>
</MapItems>
} }Comments
You're getting an error:
:ERROR{ERROR #5002: Cache error: <PROPERTY DOES NOT EXIST>zXMLTOJson+6^TestEnvironment.Custom.GENERAL.CUSTOM.XLT.XMLToJsonOperation1.1 *Parameters,EnsLib.EDI.XML}Which means :
- Class is EnsLib.EDI.XML
- It does not have Parameters property
- Error is found in the 6th line of zXMLTOJson routine in TestEnvironment.Custom.GENERAL.CUSTOM.XLT.XMLToJsonOperation1.1
6th line is probably this:
Set tSC = ..Transform(tInput,tSSKey,pRequest.Parameters,.tOutput)
and pRequest object (of EnsLib.EDI.XML class) does not have Parameters property. Your call should probably be:
Set tSC = ..Transform(tInput,tSSKey,pRequest,.tOutput)
Thanks for the advice have changed my code but come to a problem while reading my stream as there seems to an error with the XSLT XML Transformer Error: SAXParseException I do not seems to see what the problem is as I tested my XLT with the XLT Transform Wizard and it all worked fine could you please have a look at the xml and the XLT and see if you can spot where I am going wrong thanks in advance
XML
<Message><Header><Code>HOT</Code><Date>2017-12-08 11:22:34.658</Date></Header><Body><Code>HOT</Code><Name>SIDE</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>Adult</ardge><Nder>F</Nder><TBC>21</TBC><BO>14</BO><DBOC>0</DBOC><LBC>5</LBC><AB>2</AB></Body><Body><Code>HOT</Code><Name>DARS</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>OADULT</ardge><Nder>U</Nder><TBC>20</TBC><BO>16</BO><DBOC>0</DBOC><LBC>2</LBC><AB>2</AB></Body><Body><Code>HOT</Code><Name>ENTLE</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>Adult</ardge><Nder>M</Nder><TBC>22</TBC><BO>18</BO><DBOC>0</DBOC><LBC>3</LBC><AB>1</AB></Body><Body><Code>HOT</Code><Name>ROOXED</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>OADULT</ardge><Nder>U</Nder><TBC>17</TBC><BO>7</BO><DBOC>0</DBOC><LBC/><AB>9</AB></Body><Body><Code>HOT</Code><Name>DUK</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>Adult</ardge><Nder>F</Nder><TBC>20</TBC><BO>17</BO><DBOC>0</DBOC><LBC>1</LBC><AB>2</AB></Body><Body><Code>HOT</Code><Name>DALE</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>Adult</ardge><Nder>M</Nder><TBC>18</TBC><BO>15</BO><DBOC>0</DBOC><LBC>2</LBC><AB/></Body><Body><Code>HOT</Code><Name>DAN</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>OADULT</ardge><Nder>U</Nder><TBC>16</TBC><BO>8</BO><DBOC>0</DBOC><LBC/><AB>8</AB></Body><Body><Code>HOT</Code><Name>DUN</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>Adult</ardge><Nder>U</Nder><TBC>2</TBC><BO>0</BO><DBOC>0</DBOC><LBC>1</LBC><AB>1</AB></Body><Body><Code>HOT</Code><Name>DUW</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>Adult</ardge><Nder>U</Nder><TBC>3</TBC><BO>2</BO><DBOC>0</DBOC><LBC>1</LBC><AB/></Body><Body><Code>HOT</Code><Name>DUM</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>OADULT</ardge><Nder>U</Nder><TBC>22</TBC><BO>18</BO><DBOC>0</DBOC><LBC>2</LBC><AB>2</AB></Body><Body><Code>HOT</Code><Name>DUR</Name><Type>AADULT</Type><Sec>MSec</Sec><ardge>Adult</ardge><Nder>U</Nder><TBC>16</TBC><BO>13</BO><DBOC>0</DBOC><LBC>2</LBC><AB/></Body></Message>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:template match="/*[node()]">
<xsl:text>{</xsl:text><xsl:text>
</xsl:text>
<xsl:apply-templates select="." mode="detect" />
<xsl:text>
</xsl:text>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="*" mode="detect">
<xsl:choose>
<xsl:when test="name(preceding-sibling::*[1]) = name(current()) and name(following-sibling::*[1]) != name(current())">
<xsl:apply-templates select="." mode="obj-content" />
<xsl:text>
</xsl:text>
<xsl:text>]</xsl:text>
<xsl:if test="count(following-sibling::*[name() != name(current())]) > 0">, </xsl:if>
</xsl:when>
<xsl:when test="name(preceding-sibling::*[1]) = name(current())">
<xsl:apply-templates select="." mode="obj-content" />
<xsl:if test="name(following-sibling::*) = name(current())">, </xsl:if>
</xsl:when>
<xsl:when test="following-sibling::*[1][name() = name(current())]">
<xsl:text>"</xsl:text><xsl:value-of select="name()"/><xsl:text>" : [</xsl:text>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="." mode="obj-content" /><xsl:text>, </xsl:text>
<xsl:text>
</xsl:text>
</xsl:when>
<xsl:when test="count(./child::*) > 0 or count(@*) > 0">
<xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : <xsl:apply-templates select="." mode="obj-content" />
<xsl:if test="count(following-sibling::*) > 0">, </xsl:if>
</xsl:when>
<xsl:when test="count(./child::*) = 0">
<xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:apply-templates select="."/><xsl:text>"</xsl:text>
<xsl:if test="count(following-sibling::*) > 0">, </xsl:if>
<xsl:text>
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="obj-content">
<xsl:text>
</xsl:text>
<xsl:text>{</xsl:text>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="@*" mode="attr" />
<xsl:if test="count(@*) > 0 and (count(child::*) > 0 or text())">, </xsl:if>
<xsl:apply-templates select="./*" mode="detect" />
<xsl:if test="count(child::*) = 0 and text() and not(@*)">
<xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:value-of select="text()"/><xsl:text>"</xsl:text>
</xsl:if>
<xsl:if test="count(child::*) = 0 and text() and @*">
<xsl:text>"text" : "</xsl:text><xsl:value-of select="text()"/><xsl:text>"</xsl:text>
</xsl:if>
<xsl:text>}</xsl:text>
<xsl:if test="position() < last()">, </xsl:if>
</xsl:template>
<xsl:template match="@*" mode="attr">
<xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:value-of select="."/><xsl:text>"</xsl:text>
<xsl:if test="position() < last()">,</xsl:if>
</xsl:template>
<xsl:template match="node/@TEXT | text()" name="removeBreaks">
<xsl:param name="pText" select="normalize-space(.)"/>
<xsl:choose>
<xsl:when test="not(contains($pText, '
'))"><xsl:copy-of select="$pText"/></xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring-before($pText, '
'), ' ')"/>
<xsl:call-template name="removeBreaks">
<xsl:with-param name="pText" select="substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>Here's the code I ran:
Class User.XMLTest
{
/// do ##class(User.XMLTest).Test()
ClassMethod Test()
{
set source = ..GetXData("Source")
set xslt = ..GetXData("XSLT")
#dim result As %Stream.Object
set sc = ##class(%XML.XSLT.Transformer).TransformStream(source, xslt, .result)
do result.OutputToDevice()
}
ClassMethod GetXData(name) As %Stream.TmpCharacter [ CodeMode = expression ]
{
##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), name).Data
}
XData Source
{
Your Message
}
XData XSLT
{
Your XSLT
}
}
and here's the result:
{
"Message" :
{
"Header" :
{
"Code" : "HOT",
"Date" : "2017-12-08 11:22:34.658"
}, "Body" : [
{
"Code" : "HOT",
"Name" : "SIDE",
"Type" : "AADULT",
"Sec" : "MSec",
"ardge" : "Adult",
"Nder" : "F",
"TBC" : "21",
"BO" : "14",
"DBOC" : "0",
"LBC" : "5",
"AB" : "2"
},
...Check %objlasterror and also check your XML encoding, there may be problems if your encoding does not match declaration.
@Eduard Lebedyuk
sorry man given the above XLT how can I get the following Json
{
"Body" : [
{
"Code" : "HOT",
"Name" : "SIDE",
"Type" : "AADULT",
"Sec" : "MSec",
"ardge" : "Adult",
"Nder" : "F",
"TBC" : "21",
"BO" : "14",
"DBOC" : "0",
"LBC" : "5",
"AB" : "2"
},
{
"Code" : "HOT",
"Name" : "DARS",
"Type" : "AADULT",
"Sec" : "MSec",
"ardge" : "OADULT",
"Nder" : "U",
"TBC" : "20",
"BO" : "16",
"DBOC" : "0",
"LBC" : "2",
"AB" : "2"
}
]
"Code" : "HOT",
"Date" : "2017-12-08 11:22:34.658",
}
Is this expected result?
yes that the expected results even if you can not move the last two elements to be last just making something similar might help