XSL. Passing param in string - java

Here is my XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="RSA-InsurerID"/>
<xsl:param name="RSA-schema-version"/>
<xsl:template match="/">
<rsa:DriverStatusRequest xmlns:rsa="com/rsa/eosago/schema-"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InsurerID>
<xsl:value-of select="$RSA-InsurerID"
xmlns:ns2="com/rsa/eosago/schema-"/>
</InsurerID>
<IDCheckDriver>
<xsl:value-of select="ns2:DriverResponse/IDCheckDriver"
xmlns:ns2="com/rsa/eosago/schema-"/>
</IDCheckDriver>
</rsa:DriverStatusRequest>
</xsl:template>
These two params values are passed via Apache Camel.
The question is how to pass and concat the param
<xsl:param name="RSA-schema-version"/>
with xmlns:rsa="com/rsa/eosago/schema-" ?
I got my <xsl:param name="RSA-InsurerID"/> with <xsl:value-of select="$RSA-InsurerID", but i have no idea how to pass it to the value text.
I expect this output:
<?xml version="1.0" encoding="UTF-8"?>
<rsa:DriverStatusRequest xmlns:rsa="com/rsa/eosago/schema-1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InsurerID>18800000</InsurerID>
<IDCheckDriver/>
</rsa:DriverStatusRequest>
Big thanks!

Seems what you try to do is to generate a namespaces dynamically at run time.
For example have a look to this or this answers.
And try:
<xsl:template match="/">
<xsl:element name="rsa:DriverStatusRequest" namespace="com/rsa/eosago/schema-{$RSA-schema-version}" >
<InsurerID>
<xsl:value-of select="$RSA-InsurerID" />
</InsurerID>
</xsl:element>
</xsl:template>
Which will generate:
<rsa:DriverStatusRequest xmlns:rsa="com/rsa/eosago/schema-1.2">
<InsurerID>18800000</InsurerID>
</rsa:DriverStatusRequest>
But I assume there will be loot more problems coming up.

Try
<InsurerID>
<xsl:value-of select="$RSA-InsurerID"
xmlns:ns2="com/rsa/eosago/schema-{$RSA-schema-version}"/>

Related

An empty line in csv output file using xslt

Hi i am have an XML file and trying to convert it using xslt. But issue is i get a white line before the output.How do i eliminate it.
Below is my XML
<?xml version="1.0" encoding="UTF-8"?>
<UserInfo xmlns="http://XXXXXX">
<User>
<UserName>MNO</UserName>
<Userid>1234</Userid>
<address>xyz</address>
<city>ABC</city>
<state>XX</state>
<zip>000000</zip>
</User>
<User>
<UserName>DEF</UserName>
<Userid>4567</Userid>
<address>IJK</address>
<city>GHI</city>
<state>XX</state>
<zip>000000</zip>
</User>
</UserInfo>
below is my xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
UserName,Userid,address,city,state,zip
<xsl:for-each select="//User">
<xsl:value-of select="concat(UserName,',',Userid,',',address,',',city,',',state,',',zip,'
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
When ever i run the above i get a white line first and then the output.
vendorName,vendorId,vendorTaxId,addressLine1,addressLine2,city,state,zip
MNO,1234,xyz,ABC,XX,000000
DEF,4567,IJK,GHI,XX,000000
I get the white space above the nodes(UserName,UserId etc)
Use xsl:text to output literal text, e.g.:
<xsl:template match="/">
<xsl:text>UserName,Userid,address,city,state,zip
</xsl:text>
<xsl:for-each select="//User">
<xsl:value-of select="concat(UserName,',',Userid,',',address,',',city,',',state,',',zip,'
')"/>
</xsl:for-each>
</xsl:template>
The way you have it now, the entire text node is written to the output - including the line break between <xsl:template match="/"> and UserName.

Customizing/Remove name space in Soap Response - JAX-WS [duplicate]

I need to remove the namespace prefix from an un-SOAP'd message.
This is the message that has had the SOAP envelope removed. As you can see it contains ns1 prefix on the elements:
<ns1:BookingSource xmlns:ns1="urn:EDI/Booking/artifacts">
<ns1:BookingHeader>
<ns1:BookingNo>000123</ns1:BookingNo>
<ns1:BookingDate>01/01/2012</ns1:BookingDate>
<ns1:DSBookingDetail>
<ns1:BookingNo>000123</ns1:BookingNo>
<ns1:SeqNo>1</ns1:SeqNo>
<ns1:LineType>Item</ns1:LineType>
<ns1:ProductCode>Box</ns1:ProductCode>
</ns1:DSBookingDetail>
<ns1:DSBookingDetail>
<ns1:BookingNo>000123</ns1:BookingNo>
<ns1:SeqNo>2</ns1:SeqNo>
<ns1:LineType>Item</ns1:LineType>
<ns1:ProductCode>BrakeShoe</ns1:ProductCode>
</ns1:DSBookingDetail>
</ns1:DSBookingHeader>
<ns1:BookingHeader>
<ns1:BookingNo>000124</ns1:BookingNo>
<ns1:BookingDate>01/01/2012</ns1:BookingDate>
<ns1:DSBookingDetail>
<ns1:BookingNo>000124</ns1:BookingNo>
<ns1:SeqNo>1</ns1:SeqNo>
<ns1:LineType>Item</ns1:LineType>
<ns1:ProductCode>Box</ns1:ProductCode>
</ns1:DSBookingDetail>
<ns1:DSBookingDetail>
<ns1:BookingNo>000124</ns1:BookingNo>
<ns1:SeqNo>2</ns1:SeqNo>
<ns1:LineType>Item</ns1:LineType>
<ns1:ProductCode>BrakeShoe</ns1:ProductCode>
</ns1:DSBookingDetail>
</ns1:DSBookingHeader>
</ns1:BookingSource>
To this:
<BookingSource>
<BookingHeader>
<BookingNo>000123</BookingNo>
<BookingDate>01/01/2012</BookingDate>
<DSBookingDetail>
<BookingNo>000123</BookingNo>
<SeqNo>1</SeqNo>
<LineType>Item</LineType>
<ProductCode>Box</ProductCode>
</DSBookingDetail>
<DSBookingDetail>
<BookingNo>000123</BookingNo>
<SeqNo>2</SeqNo>
<LineType>Item</LineType>
<ProductCode>BrakeShoe</ProductCode>
</DSBookingDetail>
</DSBookingHeader>
<BookingHeader>
<BookingNo>000124</BookingNo>
<BookingDate>01/01/2012</BookingDate>
<DSBookingDetail>
<BookingNo>000124</BookingNo>
<SeqNo>1</SeqNo>
<LineType>Item</LineType>
<ProductCode>Box</ProductCode>
</DSBookingDetail>
<DSBookingDetail>
<BookingNo>000124</BookingNo>
<SeqNo>2</ns1:SeqNo>
<LineType>Item</LineType>
<ProductCode>BrakeShoe</ProductCode>
</DSBookingDetail>
</DSBookingHeader>
</BookingSource>
I've searched through the KB and found some hints on how to do it, but the final solution evades me.
Thanks,
Tony.
It is called namespace, below is a code to remove namespace from all elements and attributes ..
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{local-name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>

Replace parts of string on line using XSLT 2

I have a WSDL, in which I would like to override the soap address location using XSLT 2.0.
For example:
<soap:address location="https://xyz.company.com/portal/services/Service?param1=myapp&webService=TestWebService"/>
For the location attribute, I would like
xyz.company.com to become abc.company.com
myapp to become xyzapp.
I have written the following xslt:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<xsl:output method="xml"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="vLocation" select="wsdl:definitions/wsdl:service/wsdl:port/soap:address/#location"/>
<xsl:template match="#location">
<xsl:attribute name="location">
<xsl:value-of select="replace($vLocation, xyz.company.com', 'abc.company.com')"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
This works for replacing point 1 -> xyz.company.com to become abc.company.com.
But how can I also replace point 2. ->myapp to become xyzapp
Please advise.
Thanks,
You can simply call replace again as in
<xsl:template match="soap:address/#location">
<xsl:attribute name="location" select="replace(replace(., 'xyz\.company\.com', 'abc.company.com'), 'myapp', 'xyzapp')"/>
</xsl:template>

Splitting an xml based on the contents of xml either using java or xslt

I have a requirement,consider the below xml data
Input1.xml
<Envelope>
<Notification>
<Data>
<Input>ABCDEFGHIJKLMN</Input>
<Output>RESPONSEDATA</Output>
</Data>
<Data>
<Input>OPQRSTUVWXYZ</Input>
<Output>NEXTDATA</Output>
</Data>
<Data>
<Input>ALPHABETS</Input>
<Output>SOMEDATA</Output>
</Data>
</Notification>
</Envelope>
Now I want 3 output xmls with the response as shown below the file name to have first 6 characters ofABCDEFGHIJKLMN as output file name to have as shown below
(FILE1)->ABCDEF.XML
<Output>RESPONSEDATA</Output>
(FILE2)->OPQRST.XML
<Output>NEXTDATA</Output>
(FILE3)->ALPHAB.XML
<Output>SOMEDATA</Output>
Which XSLT 1.0 processor do you use? Xalan Java supports
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:redirect="http://xml.apache.org/xalan/redirect"
extension-element-prefixes="redirect"
exclude-result-prefixes="redirect">
<xsl:template match="/Envelope/Notification/Data[not(Input/*)]">
<redirect:write select="concat(substring(Input, 1, 6), '.xml')">
<xsl:copy-of select="Output"/>
</redirect:write>
</xsl:template>
<xsl:template match="/Envelope/Notification/Data[Input/*]">
<redirect:write select="concat(local-name(Input/*), '.xml')">
<xsl:copy-of select="Output"/>
</redirect:write>
</xsl:template>
</xsl:stylesheet>
Use the solution described in Your Previous Question you can then create 3 xslt files as follow, and apply the same xml input one for each xslt/output. Explain:
<xsl:copy-of select="/Envelope/Notification/Data[child::Output/text()='RESPONSEDATA']"/>
is saying, copy all "/Envelope/Notification/Data" and it content, but only for the child Output with a text value of 'RESPONSEDATA'.
ExtractResponseData.xslt
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/">
<xsl:copy-of select="/Envelope/Notification/Data[child::Output/text()='RESPONSEDATA']"/>
</xsl:template>
</xsl:stylesheet>
ExtractNextData.xslt
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/">
<xsl:copy-of select="/Envelope/Notification/Data[child::Output/text()='NEXTDATA']"/>
</xsl:template>
</xsl:stylesheet>
ExtractSomeData.xslt
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/">
<xsl:copy-of select="/Envelope/Notification/Data[child::Output/text()='SOMEDATA']"/>
</xsl:template>
</xsl:stylesheet>

Mapping two sources to one output

I want to performs XSLT on two sources.
Sourch_1.xml:
<Root>
<record>
<PolicyNumber>1</PolicyNumber>
<FirdsName>aa</FirdsName>
<LastName>aa</LastName>
</record>
<record>
<PolicyNumber>2</PolicyNumber>
<FirdsName>bb</FirdsName>
<LastName>bb</LastName>
</record>
Sourch_2.xml:
<Root>
<record>
<policy>
<PolicyNumber>1</PolicyNumber>
<city>aaCity</city>
<street>aaStreet</street>
</policy>
<policy>
<PolicyNumber>2</PolicyNumber>
<city>bbCity</city>
<street>bbStreet</street>
</policy>
</record>
I want the output to create tags which combine data from two sources based on PolicyNumber.
I want my output to be:
output.xml:
<Root>
<record_data>
<PolicyNumber>1</PolicyNumber>
<FirdsName>aa</FirdsName>
<LastName>aa</LastName>
<city>aaCity</city>
<street>aaStreet</street>
</record_data>
<record_data>
<PolicyNumber>2</PolicyNumber>
<FirdsName>bb</FirdsName>
<LastName>bb</LastName>
<city>bbCity</city>
<street>bbStreet</street>
</record_data>
How can i accomplish that using XSLT?
To process more than one XML input file, use the document() function. Make sure that additional XML files are in the folder where you put the XSLT stylesheet, too.
The line that deserves your attention is the following:
<xsl:for-each select="document('double2.xml')/root/record/policy[./PolicyNumber=current()/PolicyNumber]">
To begin with, document('double2.xml') opens the second XML file (I have dubbed it "double2.xml"). For the policy elements in this second XML file it checks whether their PolicyNumber is equal to the PolicyNumber of the record element from the first XML file that is being processed
I have slightly modified your input to make it well-formed (lowercased the root element and added its closing tag). Note that there is also a typo in it and you probably meant to write "FirstName" instead of "FirdsName".
Stylesheet
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<record_data>
<xsl:copy-of select="*"/>
<xsl:for-each select="document('double2.xml')/root/record/policy[./PolicyNumber=current()/PolicyNumber]">
<xsl:copy-of select="city|street"/>
</xsl:for-each>
</record_data>
</xsl:template>
</xsl:stylesheet>
Output
<?xml version="1.0" encoding="UTF-8"?>
<root>
<record_data>
<PolicyNumber>1</PolicyNumber>
<FirdsName>aa</FirdsName>
<LastName>aa</LastName>
<city>aaCity</city>
<street>aaStreet</street>
</record_data>
<record_data>
<PolicyNumber>2</PolicyNumber>
<FirdsName>bb</FirdsName>
<LastName>bb</LastName>
<city>bbCity</city>
<street>bbStreet</street>
</record_data>
</root>
Something like below will work for you.
NOTE : I have not ran this code. where I check not(policy) you might do some change in xpath like not(./policy)
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="Root/record">
<xsl:choose>
<xsl:when test="not(policy)">
<record_data>
<PolicyNumber><xsl:value-of select="PolicyNumber"/></PolicyNumber>
<FirdsName><xsl:value-of select="FirdsName"/></FirdsName>
<LastName><xsl:value-of select="LastName"/></LastName>
<city><xsl:value-of select="city"/></city>
<street><xsl:value-of select="street"/></street>
</record_data>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
<record_data>
<PolicyNumber><xsl:value-of select="policy/PolicyNumber"/></PolicyNumber>
<FirdsName><xsl:value-of select="policy/FirdsName"/></FirdsName>
<LastName><xsl:value-of select="policy/LastName"/></LastName>
<city><xsl:value-of select="policy/city"/></city>
<street><xsl:value-of select="policy/street"/></street>
</record_data>
</xsl:choose>
</xsl:for-each>

Categories