How to edit specific xml using xpath - java

I have got below xml which is genrated using xslt function json-to-xml(). I need to update this xml as shown in Result xml using given xpaths. I need the solution in java or xslt. Any help would be much appreciated.
XML
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
<map key="Response">
<map key="Headers">
<string key="server">Lisa</string>
<string key="Status-Code">200</string>
<string key="Content-Type">applicaton/json</string>
</map>
<map key="Payload">
<map key="root">
<array key="cars">
<map>
<string key="company">ccc</string>
<string key="model">mmm</string>
</map>
<map>
<string key="strength">666</string>
<string key="Capacity">333</string>
</map>
</array>
<array key="bikes">
<map>
<string key="company">abc</string>
<string key="model">2018</string>
</map>
</array>
</map>
</map>
</map>
</map>
XPATHS
/Response/Payload/root/cars[2]/strength=999
/Response/Payload/root/bikes/model=2019
/Response/Headers/server=WebSphere
/Response/Headers/Content-Type=text
/Response/Payload/root/cars[2]/Capacity=555
/Response/Payload/root/cars[1]/model=mmm1
/Response/Payload/root/bikes/company=xyz
/Response/Payload/root/cars[1]/company=ccc1
/Response/Headers/Status-Code=400
UPDATED RESULT XML
<map xmlns="http://www.w3.org/2005/xpath-functions">
<map key="Response">
<map key="Headers">
<string key="server">WebSphere</string>
<string key="Status-Code">400</string>
<string key="Content-Type">text</string>
</map>
<map key="Payload">
<map key="root">
<array key="cars">
<map>
<string key="company">ccc1</string>
<string key="model">mmm1</string>
</map>
<map>
<string key="strength">999</string>
<string key="Capacity">555</string>
</map>
</array>
<array key="bikes">
<map>
<string key="company">xyz</string>
<string key="model">2019</string>
</map>
</array>
</map>
</map>
</map>
</map>
My Try
I have tried converting this xml back to json using xslt function and then used com.jayway.jsonpath Jayway JsonPath library to parse/change values of json on given xpaths. And then finally changed that json again to xml using xslt function. This worked for me like charm !!
But after using this library i started facing issues in my other part of application :( . All the post request with json request body started giving 400 error. The error was "Error 400 The request sent by the client was syntactically incorrect" . I couldn't figure out the issue and may be it was due to different jar conficts.
So I am trying some other way to work. Any other library like Jayway JsonPath? Or any other solution/Suggestion will help alot.

One approach given XSLT 3 might be to transform those paths you have into XSLT 3 match templates and then create a stylesheet you can execute with the transform function (https://www.w3.org/TR/xpath-functions/#func-transform):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:axsl="http://www.w3.org/1999/XSL/Transform-alias"
exclude-result-prefixes="xs"
version="3.0">
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:output method="xml" indent="yes"/>
<xsl:param name="paths" as="xs:string">/Response/Payload/root/cars[2]/strength=999
/Response/Payload/root/bikes[1]/model=2019
/Response/Headers/server=WebSphere
/Response/Headers/Content-Type=text
/Response/Payload/root/cars[2]/Capacity=555
/Response/Payload/root/cars[1]/model=mmm1
/Response/Payload/root/bikes[1]/company=xyz
/Response/Payload/root/cars[1]/company=ccc1
/Response/Headers/Status-Code=400</xsl:param>
<xsl:param name="path-sequence" as="xs:string*" select="tokenize($paths, '\s+')!normalize-space()"/>
<xsl:variable name="stylesheet">
<axsl:stylesheet version="3.0">
<axsl:mode on-no-match="shallow-copy"/>
<xsl:for-each select="($path-sequence)">
<xsl:variable name="steps" select="tokenize(., '/')"/>
<axsl:template>
<xsl:attribute name="match">
<xsl:apply-templates select="tail($steps)" mode="step"/>
</xsl:attribute>
<axsl:copy>
<axsl:copy-of select="#*"/>
<xsl:value-of select="substring-after($steps[last()], '=')"/>
</axsl:copy>
</axsl:template>
</xsl:for-each>
</axsl:stylesheet>
</xsl:variable>
<xsl:template match=".[not(contains(., '[')) and not(contains(., '='))]" mode="step">
<xsl:if test="position() gt 1">/</xsl:if>
<xsl:sequence select="'*[#key = ''' || . || ''']'"/>
</xsl:template>
<xsl:template match=".[contains(., '=')]" mode="step">
<xsl:if test="position() gt 1">/</xsl:if>
<xsl:sequence select="'*[#key = ''' || substring-before(., '=') || ''']'"/>
</xsl:template>
<xsl:template match=".[contains(., '[')]" mode="step">
<xsl:if test="position() gt 1">/</xsl:if>
<xsl:sequence select="'*[#key = ''' || substring-before(., '[') || ''']/*[' || replace(., '^[^\[]+\[([0-9]+)\]', '$1') || ']'"/>
</xsl:template>
<xsl:template match="/">
<xsl:sequence select="transform(map {
'source-node' : .,
'stylesheet-node' : $stylesheet
})?output"/>
</xsl:template>
</xsl:stylesheet>
At https://xsltfiddle.liberty-development.net/jyyiVhv/1 I get the wanted result
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
<map key="Response">
<map key="Headers">
<string key="server">WebSphere</string>
<string key="Status-Code">400</string>
<string key="Content-Type">text</string>
</map>
<map key="Payload">
<map key="root">
<array key="cars">
<map>
<string key="company">ccc1</string>
<string key="model">mmm1</string>
</map>
<map>
<string key="strength">999</string>
<string key="Capacity">555</string>
</map>
</array>
<array key="bikes">
<map>
<string key="company">xyz</string>
<string key="model">2019</string>
</map>
</array>
</map>
</map>
</map>
</map>
that way although I had to adapt the paths including bikes to bikes[1].

Related

XSLT 3.0 Identity transform document collection?

I have one XSLT 3.0:
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:n1="urn:hl7-org:v3">
<xsl:output indent="yes" method="xml" encoding="utf-8"/>
<xsl:param name="icd10Map" as="map(xs:string, xs:string)"
select="
map {
'1742': 'C502',
'55090': 'K409',
'8442': 'S8350',
'7172': 'M2332',
'36616': 'H251',
'4550': 'K648'
}"/>
<xsl:variable name="map-keys" select="map:keys($icd10Map)"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="n1:translation[#codeSystemName = 'ICD-9-CM']/#code">
<xsl:attribute name="code">
<xsl:value-of select="$icd10Map($map-keys[translate(normalize-space(current()), '
.;', '') = .])"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
One input XML:
<?xml-stylesheet type="text/xsl" href="./Content/xsl/CDA.xsl"?>
<ClinicalDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 NIST_C32_schema/C32_CDA.xsd" xmlns="urn:hl7-org:v3" xmlns:sdtc="urn:hl7-org:sdtc">
<realmCode code="US" />
<typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040" />
<templateId root="2.16.840.1.113883.10.20.22.1.1" />
************************************************************
<id extension="TT988" root="2.16.840.1.113883.19.5.99999.1" />
<code codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" code="11504-8" displayName="Surgical Operation Note" />
<title>Operative Report</title>
****************************************************
<component>
<structuredBody>
<component>
<section>
***********************
<entry>
<act moodCode="EVN" classCode="ACT">
<templateId root="2.16.840.1.113883.10.20.22.4.65" />
<code code="10219-4" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" displayName="Preoperative Diagnosis" />
<entryRelationship typeCode="SUBJ">
<observation classCode="OBS" moodCode="EVN">
<code code="282291009" displayName="Diagnosis" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT" />
<statusCode code="completed" />
<!-- ICD-9 be transformed to ICD-10 -->
<value nullFlavor="OTH" type="CD">
<translation code="366.16" displayName="Nuclear sclerosis" codeSystem="2.16.840.1.113883.6.103" codeSystemName="ICD-9-CM" />
</value>
</observation>
</entryRelationship>
</act>
</entry>
</section>
</component>
</structuredBody>
</component>
</ClinicalDocument>
The transformation scenario in Oxygen with just one document is without issue:
*******************
<value nullFlavor="OTH" type="CD">
<translation code="H251"
displayName="Nuclear sclerosis"
codeSystem="2.16.840.1.113883.6.103"
codeSystemName="ICD-9-CM"/>
</value>
******************
However, XSLT 3.0 identity transform for collection seems working like this:
<xsl:variable name="inFile" as="node()*" select="collection('hl7.xml')"/>
<xsl:template match="/">
<xsl:text>
ICD9 Target Transformation in the collection is:
</xsl:text>
<xsl:for-each select="$inFile//n1:translation[#codeSystemName = 'ICD-9-CM']/#code">
<xsl:value-of select="$icd10Map($map-keys[translate(normalize-space(current()), '
.;', '') = .])" separator=" , "/>
</xsl:for-each>
</xsl:template>
Result:
ICD9 Target Transformation in the collection is:
H251
H251
K648
K648
K409
K409
S8350
M2332
M2332
S8350
If I change the XSLT to:
<xsl:mode on-no-match="shallow-copy"/>
<xsl:variable name="inFile" as="node()*" select="collection('hl7.xml')"/>
<xsl:template match="n1:translation[#codeSystemName = 'ICD-9-CM']/#code">
<xsl:text>
ICD9 Target Transformation in the collection is:
</xsl:text>
<xsl:for-each select="$inFile">
<xsl:attribute name="code">
<xsl:value-of select="$icd10Map($map-keys[translate(normalize-space(current()), '
.;', '') = .])" separator=" , "/>
</xsl:attribute>
</xsl:for-each>
</xsl:template>
It doesn’t appear any transform happen and is merely an extraction of the URI list in the catalog file hl7.xml.
I develop a Java application which can bulk validate documents against XSD, transform (without collection()) and finally write the documents into database. The logging is the desired result:
Engine Instantiation: com.fc.andante.sax.SAXValidateStreamTransformWrite
Schema Validation Status: files in:/ml/Andante/data/data are validated against schema file:/ml/Andante/data/operation-transform.xsd
User 'auditor' has validated files in:/ml/Andante/data/data on 2020-08-26T23:05:26.357431
*****************
Transaction Status: Authenticating database writer...
Transaction Status: User audited as 'super' is transforming document set...
Transaction Status: Document data/data/cataract.xml is successfully transformed and written into database with uri '/xslt-transform/cataract.xml'
Transaction Status: Document data/data/breast-surgery.xml is successfully transformed and written into database with uri '/xslt-transform/breast-surgery.xml'
Transaction Status: Document data/data/hernia.xml is successfully transformed and written into database with uri '/xslt-transform/hernia.xml'
Transaction Status: Document data/data/colonoscopy.xml is successfully transformed and written into database with uri '/xslt-transform/colonoscopy.xml'
Transaction Status: Document data/data/knee.xml is successfully transformed and written into database with uri '/xslt-transform/knee.xml'
Die Transaktion wurde erfolgreich abgeschlossen 2020-08-26T23:05:28.341385700
Can anyone help to solve the XSLT 3.0 Collections transform issue?
I would use a global parameter
<xsl:param name="inFiles" as="document-node()*" select="collection('hl7.xml')"/>
and then start processing with a named template
<xsl:template name="xsl:initial-template">
<xsl:for-each select="$inFiles">
<xsl:result-document href="/xslt-transform/{tokenize(document-uri(), '/')[last()]}">
<xsl:apply-templates/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
Then you can xsl:import your first XSLT sample from the question or of course edit it to insert the code I have shown. Make sure you let Saxon start with the named template (-it command line option for Saxon; in oXygen by not providing a source document).

Unmarshalling without unique node names

I am stuck trying to figure out how to unmarshall an XML file supplied by IBM Cognos.
The structure does not provide unique names for the different child nodes under the element but there is a block of metadata that defines the order of the values.
This is a simplified sample of the XML file.
<?xml version="1.0" encoding="utf-8"?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<!--
<dataset
xmlns="http://developer.cognos.com/schemas/xmldata/1/"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://developer.cognos.com/schemas/xmldata/1/ xmldata.xsd"
>
-->
<metadata>
<item name="EmployeeID" type="xs:string" length="20"/>
<item name="firstName" type="xs:string" length="50"/>
<item name="lastName" type="xs:string" length="50"/>
</metadata>
<data>
<row>
<value>EMP1</value>
<value>Joe</value>
<value>Blogs</value>
</row>
<row>
<value>EMP2</value>
<value>Mary</value>
<value>Soap</value>
</row>
</data>
</dataset>
I'm using Spring OXM and Castor for this project and I have no control over the XML format as I am pulling it via a web service from a third party system.
Update : I'm not adverse to swapping out Castor for a different marshalling/unmarshalling library.
The magic of XSLT to the rescue. By running the provided XML through the following XSLT stylesheet I was able to create an XML file that I could then unmarshall correctly.
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cognos="http://developer.cognos.com/schemas/xmldata/1/">
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
<xsl:template match="/">
<xsl:element name="DataSet">
<xsl:for-each select="//*[name()='row']">
<xsl:variable name="row" select="position()" />
<xsl:element name="Row">
<xsl:for-each select="//*[name()='item']">
<xsl:variable name="elementName" select="#name" />
<xsl:variable name="index" select="position()" />
<xsl:element name="{translate($elementName,' ','_')}">
<xsl:value-of select="//cognos:row[$row]/cognos:value[$index]" />
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This transformed the XML file as follows
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DataSet>
<Row>
<EmployeeID>EMP1</EmployeeID>
<firstName>Joe</firstname>
<lastName>Blogs</lastName>
</Row>
<Row>
<EmployeeID>EMP2</EmployeeID>
<firstName>Mary</firstname>
<lastName>Soap</lastName>
</Row>
</DataSet>

Issue with XSLT Transformation using WSO2 ESB

I struggling with XSLT transformer mediator using XSLT mediator in wso2 esb 4.8.1.
The xslt is :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:ns="http://ep.service.ims.com"
xmlns:ax21="http://ep.service.ims.com/xsd"
exclude-result-prefixes="ns fn">
<xsl:param name="amount"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//ns:getResponse" />
</xsl:template>
<xsl:template match="ns:getResponse" xmlns:ns="http://ep.service.ims.com">
<ep:credit xmlns:ep="http://ep.service.ims.com" xmlns:xsd="http://ep.service.ims.com/xsd">
<ep:info>
<xsd:amount>
<xsl:value-of select="$amount"/>
</xsd:amount>
<xsd:personInfo>
<xsd:address>
<xsl:value-of select="ns:return/ax21:address"/>
</xsd:address>
<xsd:id>
<xsl:value-of select="ns:return/ax21:id"/>
</xsd:id>
<xsd:name>
<xsl:value-of select="ns:return/ax21:name"/>
</xsd:name>
</xsd:personInfo>
</ep:info>
</ep:credit>
</xsl:template>
</xsl:stylesheet>
and the request XML is :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getResponse xmlns:ns="http://ep.service.ims.com">
<ns:return xsi:type="ax23:PersonInfo" xmlns:ax23="http://ep.service.ims.com/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ax23:address>IMS Heath, Omega C, India, bnag</ax23:address>
<ax23:id>100</ax23:id>
<ax23:name>WSO2</ax23:name>
</ns:return>
</ns:getResponse>
</soapenv:Body>
</soapenv:Envelope>
I tried the XSLT transformation in eclipse and some online tool like (http://xslt.online-toolz.com/tools/xslt-transformation.php ) and it is working fine. However when I am trying the same in WSO2 ESB, I am facing following exception.....
org.apache.synapse.mediators.transform.XSLTMediator} -
Fatal error occurred in stylesheet parsing :
net.sf.saxon.trans.XPathException:
The supplied file does not appear to be a stylesheet Value {name ='null', keyValue ='xslt1'}
{org.apache.synapse.mediators.transform.XSLTMediator}
javax.xml.transform.TransformerConfigurationException: Failed to compile stylesheet. 1 error detected.
at net.sf.saxon.PreparedStylesheet.prepare(PreparedStylesheet.java:220)
org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:170)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:225)
TID: [0] [ESB] [2014-10-08 13:53:20,705] ERROR
{org.apache.synapse.mediators.transform.XSLTMediator} -
Unable to perform XSLT transformation using :
Value {name ='null', keyValue ='xslt1'} against source XPath : s11:Body/child::*[position()=1] | s12:Body/child::*[position()=1]
reason : Error creating XSLT transformer using : Value {name ='null', keyValue ='xslt1'}
{org.apache.synapse.mediators.transform.XSLTMediator}
org.apache.synapse.SynapseException: Error creating XSLT transformer using : Value {name ='null', keyValue ='xslt1'} at
org.apache.synapse.mediators.AbstractMediator.handleException(AbstractMediator.java:313)
Caused by: javax.xml.transform.TransformerConfigurationException:
Failed to compile stylesheet. 1 error detected.
The synapse proxy xml is:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="CreditProxy" transports="https http" startOnLoad="true" trace="disable">
<target>
<inSequence>
<log level="full">
<property name="sequence" value="inSequence - request for CreditProxy"/>
</log>
<property xmlns:pep="http://com.ims.proxy" name="ORG_ID" expression="//pep:credit/pep:id"/>
<property xmlns:pep="http://com.ims.proxy" name="ORG_AMOUNT" expression="//pep:credit/pep:amount"/>
<enrich>
<source type="inline" clone="true">
<pep:get xmlns:pep="http://ep.service.ims.com">
<pep:id>?</pep:id>
</pep:get>
</source>
<target type="body"/>
</enrich>
<enrich>
<source type="property" property="ORG_ID"/>
<target xmlns:pep="http://ep.service.ims.com" xpath="//pep:get/pep:id"/>
</enrich>
<log level="full">
<property name="sequence" value="inSequence - request for PersonInfoService"/>
</log>
<property name="STATE" value="PERSON_INFO_REQUEST"/>
<send>
<endpoint key="PersonInfoEpr"/>
</send>
</inSequence>
<outSequence>
<switch source="get-property('STATE')">
<case regex="PERSON_INFO_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - response from PersonInfoService"/>
</log>
<xslt key="xslt">
<property name="amount" expression="get-property('ORG_AMOUNT')"/>
</xslt>
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - request for CreditService"/>
</log>
<property name="STATE" value="CREDIT_REQUEST"/>
<send>
<endpoint key="CreditEpr"/>
</send>
</case>
<case regex="CREDIT_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 02 - response from CreditService"/>
</log>
<send/>
</case>
</switch>
</outSequence>
</target>
<publishWSDL uri="file:resources/CreditProxy.wsdl"/>
</proxy>
What may be the cause of the exception if the XSLT transformation is working fine in other tool ?
The key in the proxy is correct. I might have pasted the wrong XML proxy,
Here is the proxy:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="CreditProxy"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log level="full">
<property name="sequence" value="inSequence - request for CreditProxy"/>
</log>
<property xmlns:pep="http://com.ims.proxy"
name="ORG_ID"
expression="//pep:credit/pep:id"/>
<property xmlns:pep="http://com.ims.proxy"
name="ORG_AMOUNT"
expression="//pep:credit/pep:amount"/>
<enrich>
<source type="inline" clone="true">
<pep:get xmlns:pep="http://ep.service.ims.com">
<pep:id>?</pep:id>
</pep:get>
</source>
<target type="body"/>
</enrich>
<enrich>
<source type="property" clone="true" property="ORG_ID"/>
<target xmlns:pep="http://ep.service.ims.com" xpath="//pep:get/pep:id"/>
</enrich>
<log level="full">
<property name="sequence" value="inSequence - request for PersonInfoService"/>
</log>
<property name="STATE" value="PERSON_INFO_REQUEST"/>
<send>
<endpoint key="PersonInfoEpr"/>
</send>
</inSequence>
<outSequence>
<switch source="get-property('STATE')">
<case regex="PERSON_INFO_REQUEST">
<log level="full">
<property name="sequence"
value="outSequence - STATE 01 - response from PersonInfoService"/>
</log>
<xslt key="xslt1">
<property name="amount" expression="get-property('ORG_AMOUNT')"/>
</xslt>
<log level="full">
<property name="sequence"
value="outSequence - STATE 01 - request for CreditService"/>
</log>
<property name="STATE" value="CREDIT_REQUEST"/>
<send>
<endpoint key="CreditEpr"/>
</send>
</case>
<case regex="CREDIT_REQUEST">
<log level="full">
<property name="sequence"
value="outSequence - STATE 02 - response from CreditService"/>
</log>
<send/>
</case>
</switch>
</outSequence>
</target>
<publishWSDL uri="file:resources/creditproxy/CreditProxy.wsdl"/>
<description/>
</proxy>
Local entry:
<localEntry xmlns="http://ws.apache.org/ns/synapse" key="xslt1" src="file:resources/creditproxy/personToCredit.xslt"></localEntry>
There was a problem with the local entry. Finally, I was able to fix this issue by adding a local entry like this in the synapse config
<localEntry key="xslt99">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ax21="http://ep.service.ims.com/xsd"
xmlns:ns="http://ep.service.ims.com"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
version="1.0"
exclude-result-prefixes="ns fn">
<xsl:param name="amount"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//ns:getResponse"/>
</xsl:template>
<xsl:template match="ns:getResponse">
<ep:credit xmlns:ep="http://ep.service.ims.com" xmlns:xsd="http://ep.service.ims.com/xsd">
<ep:info>
<xsd:amount>
<xsl:value-of select="$amount"/>
</xsd:amount>
<xsd:personInfo>
<xsd:address>
<xsl:value-of select="ns:return/ax21:address"/>
</xsd:address>
<xsd:id>
<xsl:value-of select="ns:return/ax21:id"/>
</xsd:id>
<xsd:name>
<xsl:value-of select="ns:return/ax21:name"/>
</xsd:name>
</xsd:personInfo>
</ep:info>
</ep:credit>
</xsl:template>
</xsl:stylesheet>
<description/>
</localEntry>
Initially I was trying to add the local entries like this
<localEntry xmlns="http://ws.apache.org/ns/synapse" key="xslt1" src="file:resources/creditproxy/personToCredit.xslt"></localEntry>
But still I don't know how to specify a xslt file in local entry.?

convert xml file into csv format sing camel?

i want to create .xml file into csv file using camel. here is my code
CamelContext context = new DefaultCamelContext();
from("file://Input?fileName=test.xml").marshal().csv().to("file://test?fileName=test.csv");
context.start();
But its't creating any file in desired folder "test".
Please spend just a bit more time on the Camel docs, and try out the examples, and read the FAQ. And the introduction articles and whatnot.
The code above isn't even valid, as you would need to put it inside a RouteBuilder.
Also when you start CamelContext, read the javadoc of the start method. And read this FAQ
http://camel.apache.org/running-camel-standalone-and-have-it-keep-running.html
Also Camel offers a tracer so you can see the message flow as the messages are being processed. The tracer will be default log this at INFO level to the logger.
http://camel.apache.org/tracer
Here is a sample using camel
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:src/xmldata?noop=true"/>
<to uri="xslt:file:src/main/fruits.xslt"/>
<to uri="file://TESTOUT?fileName=output.csv"/>
</route>
</camelContext>
sample xml file in src/xmldata folder
<AllFruits xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- All fruits below. -->
<Fruit>
<FruitId>Bannana</FruitId>
<FruitColor>Yellow</FruitColor>
<FruitShape>Moon</FruitShape>
<Customer>
<Name>Joe</Name>
<NumberEaten>5</NumberEaten>
<Weight>2.6</Weight>
</Customer>
<Customer>
<Name>Mark</Name>
<NumberEaten>8</NumberEaten>
<Weight>5.0</Weight>
</Customer>
</Fruit>
</AllFruits>
src/main/fruits.xslt
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text" encoding="ISO-8859-1" />
<xsl:variable name="newline" select="'
'"/>
<xsl:template match="Fruit">
<xsl:for-each select="Customer">
<xsl:value-of select="preceding-sibling::FruitId" />
<xsl:text>,</xsl:text>
<xsl:value-of select="NumberEaten" />
<xsl:text>,</xsl:text>
<xsl:value-of select="Weight" />
<xsl:value-of select="$newline" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Remove XML content retaining a given Node (Java parser)

In the XML example below, using a java parser how to keep the content under the tag AND followed by center and remove everything else?
The tag might have other instances when is followed by other tags than center, and those has to be discarded.
<xml>
<A>
<B>
.
.
.
<parameter>
<parameterid>center</parameterid>
<name>Center</name>
<keyframe>
<when>1</when>
<value>
<horiz>100</horiz>
<vert>100</vert>
</value>
</keyframe>
<keyframe>
<when>2</when>
<value>
<horiz>150</horiz>
<vert>150</vert>
</value>
</keyframe>
</parameter>
<parameter>
...
</parameter>
<parameter>
...
</parameter>
.
.
.
</B>
</A>
</xml>
So the output will look like:
<parameter>
<parameterid>center</parameterid>
<name>Center</name>
<keyframe>
<when>1</when>
<value>
<horiz>100</horiz>
<vert>100</vert>
</value>
</keyframe>
<keyframe>
<when>2</when>
<value>
<horiz>150</horiz>
<vert>150</vert>
</value>
</keyframe>
</parameter>
Please advise. Thanks!
You can use Java Regexp to remove unneeded content, and then parse only needed part f.e.
String sourceXML = readFileToString("source.xml")
final Pattern pattern = Pattern.compile(".*(<parameter>.+</parameter>).*",Pattern.DOTALL);
Matcher matcher = pattern.matcher(sourceXML);
if (matcher.find()) {
String xmlToParse = matcher.group(0);
someDomOrSaxParser.parseFromString(xmlToParse)
}else
System.out.println("NO MATCH");
This would be a good job for an XSLT stylesheet.
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:apply-templates select="node()|#*"/>
</xsl:template>
<xsl:template match="parameter[parameterid='center']">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
applied to the input in the question, produces the following output:
<parameter>
<parameterid>center</parameterid>
<name>Center</name>
<keyframe>
<when>1</when>
<value>
<horiz>100</horiz>
<vert>100</vert>
</value>
</keyframe>
<keyframe>
<when>2</when>
<value>
<horiz>150</horiz>
<vert>150</vert>
</value>
</keyframe>
</parameter>
If you have any questions on using XSLT in Java, please take a look at this question.

Categories

Resources