My source XML is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:DriverResponse xmlns:ns2="com/rsa/eosago/schema-1.1" xmlns:ns3="com/rsa/dkbm/schema-1.5">
<IDCheckDriver>84714718</IDCheckDriver>
<ErrorList>
<ErrorInfo>
<Code>2</Code>
<Message>Принят в обработку</Message>
</ErrorInfo>
</ErrorList>
</ns2:DriverResponse>
Wanted 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>84714718</IDCheckDriver>
</rsa:DriverStatusRequest>
I expect this output using this XSL wich is called from Apache Camel:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:param name="RSA-InsurerID"/>
<xsl:param name="EOSAGO-schema-version"/>
<xsl:param name="schema" select="concat('com/rsa/eosago/schema-', $EOSAGO-schema-version)"/>
<xsl:variable name="schemaUrlDummy">
<xsl:element name="ns2:dummy" namespace="{$schema}"/>
</xsl:variable>
<xsl:variable name="NS" select="ext:node-set($schemaUrlDummy)/*/namespace::ns2"/>
<xsl:template match="/">
<xsl:element name="rsa:DriverStatusRequest" namespace="com/rsa/eosago/schema-{$EOSAGO-schema-version}">
<InsurerID>
<xsl:value-of select="$RSA-InsurerID"/>
</InsurerID>
<xsl:element name="IDCheckDriver">
<xsl:copy-of select="namespace::*[not(name()='ns2')]"/>
<xsl:copy-of select="$NS"/>
<xsl:value-of select="ns2:DriverResponse/IDCheckDriver"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Camel settings:
<setHeader headerName="RSA-InsurerID">
<constant>18800000</constant>
</setHeader>
<setHeader headerName="EOSAGO-schema-version">
<constant>1.2</constant>
</setHeader>
<to uri="xslt:com/rsa/eosago/xsl/DriverResponse2DriverStatusRequest.xsl"/>
The problem is that i get this error stacktrace
Failed to resolve endpoint: xslt://com/rsa/eosago/xsl/DriverResponse2DriverStatusRequest.xsl due to: Namespace prefix 'ns2' is undeclared.
Failed to resolve endpoint: xslt://com/rsa/eosago/xsl/DriverResponse2DriverStatusRequest.xsl due to: Namespace prefix 'ns2' is undeclared.
javax.xml.transform.TransformerConfigurationException: Namespace prefix 'ns2' is undeclared.
Why compiler throws exception on namespace that was created dinamically?
This is very confusing. Why can't you do simply:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="RSA-InsurerID"/>
<xsl:param name="EOSAGO-schema-version"/>
<xsl:template match="/*">
<xsl:element name="rsa:DriverStatusRequest" namespace="com/rsa/eosago/schema-{$EOSAGO-schema-version}">
<InsurerID>
<xsl:value-of select="$RSA-InsurerID"/>
</InsurerID>
<IDCheckDriver>
<xsl:value-of select="IDCheckDriver"/>
</IDCheckDriver>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Working demo: http://xsltransform.net/pPzifqv
Related
I need to update xml file with adding 2 to the value but within different tag
eg:
data.xml
<?xml version="1.0"?>
<data>
<tag1>2</tag1>
<tag2>6</tag2>
<tag10>7</tag10>
<string>nochange_string</string>
</data>
to updated_data.xml
<?xml version="1.0"?>
<newdata>
<tag1>4</tag1>
<tag2>8</tag2>
<tag10>9</tag10>
<string>nochange_string</string>
</newdata>
I am aware that I would need to call a method to add 2 to each tag except last 'string' tag but I am stuck to keep the tag# as it was but everything should be in the different tag called 'newdata'. How would I do this? Thanks in advance!
A method by using XSLT makes it simple.
Input XML
<?xml version="1.0"?>
<data>
<tag1>2</tag1>
<tag2>6</tag2>
<tag10>7</tag10>
<string>nochange_string</string>
</data>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/data">
<newdata>
<xsl:apply-templates select="#*|node()"/>
</newdata>
</xsl:template>
<xsl:template match="*[starts-with(local-name(), 'tag')]">
<xsl:copy>
<xsl:value-of select=". + 2"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output XML
<?xml version='1.0' encoding='utf-8' ?>
<newdata>
<tag1>4</tag1>
<tag2>8</tag2>
<tag10>9</tag10>
<string>nochange_string</string>
</newdata>
how to replace the child tag name with xsl.
here the below is my structure of xml.
<Checkpax xmlns="http://xml.api.com/test">
<customerLevel>
<customerDetails>
<paxDetails>
<surname>MUKHERJEE</surname>
<type>A</type>
<gender>M</gender>
</paxDetails>
<otherPaxDetails>
<givenName>JOY</givenName>
<title>MR</title>
<age>11</age>
</otherPaxDetails>
<otherPaxDetails>
<title>MR</title>
</otherPaxDetails>
</customerDetails>
<staffDetails>
<staffInfo/>
<staffCategoryInfo>
<attributeDetails>
<attributeType>NA</attributeType>
</attributeDetails>
</staffCategoryInfo>
</staffDetails>
<productLevel>
<legLevel>
<legLevelIndicator>
<statusDetails>
<indicator>abc</indicator>
<action>1</action>
</statusDetails>
</legLevelIndicator>
</legLevel>
</productLevel>
<CustomerLevel>
<legLevel>
<legLevelIndicator>
<statusDetails>
<indicator>cde</indicator>
<action>1</action>
</statusDetails>
</legLevelIndicator>
</legLevel>
</CustomerLevel>
</customerLevel>
</Checkpax>
The below is my XSL file
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="customerLevel/productLevel/legLevel/legLevelIndicator/statusDetails">
<statusInformation>
<xsl:apply-templates select="#*|node()" />
</statusInformation>
</xsl:template>
</xsl:stylesheet>
here the statusDetails name should be changed as staffInformation inside the ProductLevel/LeglevelIndicator . Kindly give me the suggestion for doing this.
The below is expected result
<Checkpax xmlns="http://xml.api.com/test">
<customerLevel>
<customerDetails>
<paxDetails>
<surname>MUKHERJEE</surname>
<type>A</type>
<gender>M</gender>
</paxDetails>
<otherPaxDetails>
<givenName>JOY</givenName>
<title>MR</title>
<age>11</age>
</otherPaxDetails>
<otherPaxDetails>
<title>MR</title>
</otherPaxDetails>
</customerDetails>
<staffDetails>
<staffInfo/>
<staffCategoryInfo>
<attributeDetails>
<attributeType>NA</attributeType>
</attributeDetails>
</staffCategoryInfo>
</staffDetails>
<productLevel>
<legLevel>
<legLevelIndicator>
<statusInformation>
<indicator>abc</indicator>
<action>1</action>
</statusInformation>
</legLevelIndicator>
</legLevel>
</productLevel>
<CustomerLevel>
<legLevel>
<legLevelIndicator>
<statusDetails>
<indicator>cde</indicator>
<action>1</action>
</statusDetails>
</legLevelIndicator>
</legLevel>
</CustomerLevel>
</customerLevel>
</Checkpax>
the statusDetails name should be changed as staffInformation inside
the ProductLevel/LeglevelIndicator
Try it this way:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://xml.api.com/test"
exclude-result-prefixes="ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns0:productLevel/ns0:legLevel/ns0:legLevelIndicator/ns0:statusDetails">
<staffInformation xmlns="http://xml.api.com/test">
<xsl:apply-templates/>
</staffInformation>
</xsl:template>
</xsl:stylesheet>
I was trying to find a way to convert the XML tags to their respective unique address like xPath. Nd I found an XSLT, where XML is processed and the unique address is created only for the nodes which doesnt have child elements and with attributes. [link]:Generate/get xpath from XML node java
XSLT :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vApos">'</xsl:variable>
<xsl:template match="*[#* or not(*)] ">
<xsl:if test="not(*)">
<xsl:apply-templates select="ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('=',$vApos,.,$vApos)"/>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:apply-templates select="#*|*"/>
</xsl:template>
<xsl:template match="*" mode="path">
<xsl:value-of select="concat('/',name())"/>
<xsl:variable name="vnumPrecSiblings" select=
"count(preceding-sibling::*[name()=name(current())])"/>
<xsl:if test="$vnumPrecSiblings">
<xsl:value-of select="concat('[', $vnumPrecSiblings +1, ']')"/>
</xsl:if>
</xsl:template>
<xsl:template match="#*">
<xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('[#',name(), '=',$vApos,.,$vApos,']')"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
when passed to this
<?xml version="1.0" encoding="UTF-8"?>
<root>
<main>
<tag1>001</tag1>
<tag2>002</tag2>
<tag3>
<tag4>004</tag4>
</tag3>
<tag2>002</tag2>
<tag5>005</tag5>
</main>
</root>
produces
/root/main/tag1='001' /root/main/tag2='002' /root/main/tag3/tag4='004' /root/main/tag2[2]='002' /root/main/tag5='005'
So I need the xslt to generate in the following way
/root
/root/main
/root/main/tag1
/root/main/tag2
/root/main/tag3
/root/main/tag3/tag4
/root/main/tag2[2]
/root/main/tag5
Also I dont need values. So please help me with this
Your result could be produced rather simply by:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="*">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="name()" />
<xsl:variable name="i" select="count(preceding-sibling::*[name()=name(current())])"/>
<xsl:if test="$i">
<xsl:value-of select="concat('[', $i + 1, ']')"/>
</xsl:if>
<xsl:if test="position()!=last()">
<xsl:text>/</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>
Note that this does not process attributes (or any other type of nodes other than elements).
I have xml like this
<mets:mets xmlns:mets="http://www.loc.gov/METS/">
<mets:fileSec>
<mets:fileGrp ID="REP1">
<mets:file ID="FL1">
<mets:FLocat LOCTYPE="URL" xlin:href="1.jpg" xmlns:xlin="http://www.w3.org/1999/xlink"/>
</mets:file>
</mets:fileGrp>
<mets:fileGrp ID="REP2">
<mets:file ID="FL2">
<mets:FLocat LOCTYPE="URL" xlin:href="1.tif" xmlns:xlin="http://www.w3.org/1999/xlink"/>
</mets:file>
</mets:fileGrp>
<mets:fileGrp ID="REP3">
<mets:file ID="FL3">
<mets:FLocat LOCTYPE="URL" xlin:href="2.jpg" xmlns:xlin="http://www.w3.org/1999/xlink"/>
</mets:file>
</mets:fileGrp>
</mets:fileSec>
</mets:mets>
I want to get as output IDs only files with jpg extention -> FL1, FL3.
I have problems with my xsl file :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:mets="http://www.loc.gov/METS/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mods="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-0.xsd"
exclude-result-prefixes="xlin">
<xsl:output method="html" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/">
<xsl:for-each select="//mets:fileSec/mets:fileGrp/mets:file">
<xsl:variable name="currentID" select="#ID" />
<xsl:for-each select="//mets:fileSec/mets:fileGrp/mets:file/mets:FLocat">
<xsl:variable name="testVariable" select="#xlink:href" xmlns:xlink="http://www.w3.org/1999/xlink" />
<xsl:choose>
<xsl:when test="contains($testVariable, '.jpg')"><xsl:value-of select="$currentID"/>,</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
But after transform I get error output as : FL1,FL1,FL2,FL2,FL3,FL3,
Please, help me with XSL.
Thank you!
Would something like this work for you?
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mets="http://www.loc.gov/METS/"
xmlns:xlin="http://www.w3.org/1999/xlink">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:for-each select="mets:mets/mets:fileSec/mets:fileGrp/mets:file[contains(mets:FLocat/#xlin:href, '.jpg')]">
<xsl:value-of select="#ID"/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I have xml like below
<rnp xmsns="v1">
<ele1 line="1">
<ele2></ele2>
</ele1>
</rnp>
I want to change it to
<rnp xmsns="v2">
<ele1 line="1">
<ele2></ele2>
</ele1>
</rnp>
using xslt 1.0.
I am using below xsl.
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="v2">
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#*|*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="rnp">
<rnp>
<xsl:apply-templates select="*"/>
</rnp>
</xsl:template>
</xsl:stylesheet>
But this xsl does not copy the attributes so line attribute is not generated in output.
sample output
<?xml version="1.0" encoding="UTF-8"?><rnp xmlns="v2"><ele1>1
<ele2/>
</ele1></rnp>
How to change only the text of xmlns attrbiute using xslt? Is there any other way to change xmlns using xslt? I have only option of xslt 1.0.
Thanks.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pNS" select="'v2'"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[true()]">
<xsl:element name="{local-name()}" namespace="{$pNS}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document (corrected to make it in the namespace "v1":
<rnp xmlns="v1">
<ele1 line="1">
<ele2></ele2>
</ele1>
</rnp>
produces the wanted, correct result:
<rnp xmlns="v2">
<ele1 line="1">
<ele2/>
</ele1>
</rnp>
Do note:
The desired new default namespace is passed to the transformation as an external parameter -- thus the smae transformation without any modification can be used in every case when the default namespace must be modified.
This unusual looking template match: <xsl:template match="*[true()]"> makes it possible to avoid the XSLT processors "recoverable ambiguity error" messages if we had coded it just as <xsl:template match="*"> and is shorter and more elegant than specifying a priority.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="v2">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Output:
<rnp xmlns="v2">
<ele1 line="1">
<ele2 />
</ele1>
</rnp>