Replace strings XSLT - xslt

i'm stucked. Please help me with a little problem.
I have to change just two specific lines in XML file like this:
<?xml version="1.0" encoding="UTF-8"?>
<max:PublishTP_WORKORDER xmlns:max="http://www.ibm.com/maximo" creationDateTime="2014-04-11T10:43:51+04:00" transLanguage="RU" baseLanguage="EN" messageID="1397198631936413520" maximoVersion="7 5 20130829-1209 V7510--1" event="1">
<TP_WORKORDERSet xmlns="http://www.ibm.com/maximo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<WORKORDER action="Replace">
<ACTCOST xsi:nil="true"/>
<ACTFINISH xsi:nil="true"/>
<ACTINTLABCOST>0.0</ACTINTLABCOST>
<ACTINTLABHRS>0.0</ACTINTLABHRS>
<ACTLABCOST>0.0</ACTLABCOST>
<ACTLABHRS>0.0</ACTLABHRS>
<ACTMATCOST>0.0</ACTMATCOST>
<ACTOUTLABCOST>0.0</ACTOUTLABCOST>
<ACTOUTLABHRS>0.0</ACTOUTLABHRS>
<ACTSERVCOST>0.0</ACTSERVCOST>
<ACTSTART>2013-11-08T12:03:26+04:00</ACTSTART>
<ACTTOOLCOST>0.0</ACTTOOLCOST>
<ADDRESS/>
<AMCREW/>
<AMS>0</AMS>
<AOS>0</AOS>
...........................
<WORKORDERID>10</WORKORDERID>
<WORKPACKMTLSTATUS/>
<WORKTYPE/>
<WOSEQUENCE xsi:nil="true"/>
</WORKORDER>
</TP_WORKORDERSet>
</max:PublishTP_WORKORDER>
I need to replace "PublishTP_WORKORDER" with "Create_WORKORDER", both open and close tags.
It works fine with:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:max="http://www.ibm.com/maximo" version="1.0">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/max:PublishTP_WORKORDER">
<xsl:element name="max:CreateTP_WORKORDER">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
But in XML file it could be "PublishTP_WORKORDER2" or "PublishTP_WORKORDER3" and so on.
It should be changed to "CreateTP_WORKORDER2", "CreateTP_WORKORDER3" etc
And this XSLT scheme stops working. It's just doesn't recognize strings with added numeric symbols. How could i turn it out? Thanks in advance.

It's always root element
Then how about:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:max="http://www.ibm.com/maximo">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:variable name="suffix" select="substring-after(local-name(), 'PublishTP_WORKORDER')" />
<xsl:element name="max:CreateTP_WORKORDER{$suffix}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

Related

How to remove a specific prefix using XSLT

I need to remove the ns0: prefix from the RecuperarCopiaResult node.
From <ns0:RecuperarCopiaResult> to <RecuperarCopiaResult>
Follows Input XML
<?xml version="1.0" encoding="UTF-8"?>
<ns0:RecuperarCopiaResponse xmlns:ns0="http://tempuri.org/">
<ns0:RecuperarCopiaResult><![CDATA[<Abastecimento_NF
ULTIMO_PONTEIRO="447050"><Abastecimento_NFRow><DT_PROCESS>6/2/2018
1:46:08</DT_PROCESS><CD_ABASTECIMENTO>123936138</CD_ABASTECIMENTO>
<CD_VEICULO>479077</CD_VEICULO><CD_TIPO_REGISTRO>1</CD_TIPO_REGISTRO>
<NR_BANCO>237</NR_BANCO><CD_REDE>801</CD_REDE><DC_REDE>801</DC_REDE>
<COD_POSTO>244</COD_POSTO><COD_FROTA>4941</COD_FROTA>
<COD_SUBFROTA>11264</COD_SUBFROTA><DC_SUBFROTA>R2C</DC_SUBFROTA>
<CD_COMBUSTIVEL>S</CD_COMBUSTIVEL><DC_COMBUSTIVEL>S</DC_COMBUSTIVEL>
<NR_UVE></NR_UVE><DC_PLACA>KWG8687</DC_PLACA><NM_MOTORISTA>
</NM_MOTORISTA><NR_KM_ATUAL>226076</NR_KM_ATUAL>
<NR_QTD_LITROS>139,55</NR_QTD_LITROS>
<NR_QTD_LITROS_TOTAL>139,55</NR_QTD_LITROS_TOTAL>
<CD_STATUS_ABASTECIMENTO>S</CD_STATUS_ABASTECIMENTO>
</Abastecimento_NFRow></Abastecimento_NF>]]></ns0:RecuperarCopiaResult>
</ns0:RecuperarCopiaResponse>
I am using the following xslt code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:SOAP-
ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://tempuri.org/">
<xsl:output encoding='UTF-8' method="xml" indent="yes" omit-xml-
declaration="yes" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SOAP-ENV:*">
<xsl:apply-templates select="#* | node()"/>
</xsl:template>
<xsl:template match="ns0:*">
<xsl:element name="ns0:{local-name()}"
namespace="http://www.supergasbras.com.br/service/CtfAbastecimento">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
Following is the expected XML:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:RecuperarCopiaResponse
xmlns:ns0="http://www.supergasbras.com.br/service/CtfAbastecimento">
<RecuperarCopiaResult>
<Abastecimento_NF ULTIMO_PONTEIRO="447050">
<Abastecimento_NFRow>
<DT_PROCESS>6/2/2018 1:46:08</DT_PROCESS>
<CD_ABASTECIMENTO>123936138</CD_ABASTECIMENTO>
<CD_VEICULO>479077</CD_VEICULO>
<CD_TIPO_REGISTRO>1</CD_TIPO_REGISTRO>
<NR_BANCO>237</NR_BANCO>
<CD_REDE>801</CD_REDE>
<DC_REDE>801</DC_REDE>
<COD_POSTO>244</COD_POSTO>
<COD_FROTA>4941</COD_FROTA>
<COD_SUBFROTA>11264</COD_SUBFROTA>
<DC_SUBFROTA>R2C</DC_SUBFROTA>
<CD_COMBUSTIVEL>S</CD_COMBUSTIVEL>
<DC_COMBUSTIVEL>S</DC_COMBUSTIVEL>
<NR_UVE/>
<DC_PLACA>KWG8687</DC_PLACA>
<NM_MOTORISTA/>
<NR_KM_ATUAL>226076</NR_KM_ATUAL>
<NR_QTD_LITROS>139,55</NR_QTD_LITROS>
<VL_PRECO_UNITARIO>3,798</VL_PRECO_UNITARIO>
<VL_PRECO_AEP>3,798</VL_PRECO_AEP>
<VL_VALOR_TOTAL>530,01</VL_VALOR_TOTAL>
<DT_EVENTO>5/2/2018 14:37:00</DT_EVENTO>
<DT_DEBITO>26/2/2018 0:00:00</DT_DEBITO>
<DT_CREDITO>27/2/2018 0:00:00</DT_CREDITO>
<NOMEARQ>T2060218.ZZ001305.00244</NOMEARQ>
<NR_KM_PERCORRIDA>365</NR_KM_PERCORRIDA>
<NR_QTD_LITROS_TOTAL>139,55</NR_QTD_LITROS_TOTAL>
<CD_STATUS_ABASTECIMENTO>S</CD_STATUS_ABASTECIMENTO>
</Abastecimento_NFRow>
</Abastecimento_NF>
</RecuperarCopiaResult>
</ns0:RecuperarCopiaResponse>
Your question says one thing, your expected result shows something quite different. Try it this way:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tmp="http://tempuri.org/"
exclude-result-prefixes="tmp">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/tmp:RecuperarCopiaResponse">
<ns0:RecuperarCopiaResponse xmlns:ns0="http://www.supergasbras.com.br/service/CtfAbastecimento">
<xsl:apply-templates/>
</ns0:RecuperarCopiaResponse>
</xsl:template>
<xsl:template match="tmp:RecuperarCopiaResult">
<RecuperarCopiaResult>
<xsl:value-of select="." disable-output-escaping="yes"/>
</RecuperarCopiaResult>
</xsl:template>
</xsl:stylesheet>

Convert string to binary base64

Is there any way on how to convert a string to binary base64? I've seen many references but it didn't work in my end. For example I have this input file:
<RootElement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Data>
<Binary>
<RawData>This element should convert string to binary base64.</RawData>
</Binary>
</Data>
</RootElement>
I need to generate:
<RootElement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Data>
<Binary>
<RawData>VGhpcyBlbGVtZW50IHNob3VsZCBjb252ZXJ0IHN0cmluZyB0byBiaW5hcnkgYmFzZTY0Lg==</RawData>
</Binary>
</Data>
I created an xslt and used the namespace I've seen online:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dp="http://www.datapower.com/extensions">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="RawData">
<xsl:element name="RawData">
<xsl:value-of select="dp:encode(., 'base-64')"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Thank you.
There is a pure XSLT 1.0 solution that works for any XSLT processor: JAXP, Saxon, Xalan, Xsltproc, Microsoft:
Download base64.xsl
Download base64_binarydatamap.xml
Use XSLT 1.0:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b64="https://github.com/ilyakharlamov/xslt_base64">
<xsl:output method="xml"/>
<xsl:include href="base64.xsl"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/RootElement/Data/Binary/RawData">
<xsl:call-template name="b64:encode">
<xsl:with-param name="asciiString" select="text()"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

XSL rename element name but namespace in the wrong place

I have an xml and i want to rename/changes the element name and leave everthing unchanges but i facing the unexpected result.
Incoming XML
<?xml version="1.0" encoding="utf-8"?>
<PublishVENDOR baseLanguage="EN" messageID="507085.1468382418796837538" event="1" xmlns="http://store/companies" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<VENDORSet>
<COMPANIES action="Replace">
<ADDRESS1>32 SUMNER STREET</ADDRESS1>
<ADDRESS2>HARTFORD</ADDRESS2>
<ADDRESS3>CT</ADDRESS3>
<ADDRESS4>03342</ADDRESS4>
</COMPANIES>
</VENDORSet>
</PublishVENDOR>
XSL Map
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://store/companies" version="1.0">
<xsl:template match="/ns:PublishVENDOR">
<xsl:element name="SyncVENDOR">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The result
<?xml version="1.0" encoding="utf-8"?>
<SyncMXVENDOR baseLanguage="EN" messageID="507085.1468382418796837538" event="1">
<VENDORSet xmlns="http://www.ibm.com/maximo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<COMPANIES action="Replace">
<ADDRESS1>32 SUMNER STREET</ADDRESS1>
<ADDRESS2>HARTFORD</ADDRESS2>
<ADDRESS3>CT</ADDRESS3>
<ADDRESS4>03342</ADDRESS4>
</COMPANIES>
</VENDORSet>
</SyncVENDOR>
The result that i want is
<?xml version="1.0" encoding="utf-8"?>
<SyncVENDOR baseLanguage="EN" messageID="507085.1468382418796837538" event="1" xmlns="http://store/companies" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<VENDORSet>
<COMPANIES action="Replace">
<ADDRESS1>32 SUMNER STREET</ADDRESS1>
<ADDRESS2>HARTFORD</ADDRESS2>
<ADDRESS3>CT</ADDRESS3>
<ADDRESS4>03342</ADDRESS4>
</COMPANIES>
</VENDORSet>
</SyncVENDOR>
Please somebody help me... and i'm sorry that my english is not good too
Change
<xsl:template match="/ns:PublishVENDOR">
<xsl:element name="SyncVENDOR">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
to
<xsl:template match="/ns:PublishVENDOR">
<SyncVENDOR xmlns="http://store/companies">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="#*|node()"/>
</SyncVENDOR>
</xsl:template>

XSLT/XSL recursive nested elements

I need create a recursive transformation in XSL,
input xml
<root><foo1 /><foo2 /><foo3 /></root>
output
<root>
<foo1>
<foo2>
<foo3>
</foo3>
</foo2>
<foo1>
</root>
Thanks a lot for any help...
Try something like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="*[1]" />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="following-sibling::*[1]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Which will generate the following output:
<?xml version="1.0"?>
<root>
<foo1>
<foo2>
<foo3/>
</foo2>
</foo1>
</root>

how to remove a part of attribut to a node in xml file using xslt

I have the following xml code:
<OML>
<bg-def xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="EX1"/>
</OML>
I want to remove the attribute xmlns:xsi and its value using XSLT, so that the result will look like this:
<OML>
<bg-def name="EX1"/>
</OML>
I tryied to do this with the following XSLT code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:ex="http://exslt.org/dates-and-times" extension-element-prefixes="ex">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no" xml:space="preserve"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="bg-def|# xmlns:xsi"/>
</xsl:transform>
Before I finished to write my code, my editor warned me that:
"W Namespace prefix xmlns has not been declared".
When I remove the expression :xsi and just write xmlns, there is no warning more. But when I compile and execute my program, nothing happens and I don't get the expected output.
I try also to change the last line of my xslt file with this:
<xsl:template match="bg-def|# name"/>
then the result is looking like this:
<OML>
<bg-def xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</OML>
That means, the attribute name has been removed very well. But I want to do this with the attribute xmlns:xsi.
Can someone help me to do this please?
Thanks for any help.
Franky
Use following template for bd-def node:
<xsl:template match="bg-def">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
Instead of
<xsl:template match="bg-def|# name"/>
This template will create node bg-def and copy all it context nodes and attributes, but not namespaces
Check similar question:
remove namespace for a perticular element
Update:
Source file:
<OML>
<bg-def xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="EX1"/>
</OML>
Stylesheet:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:ex="http://exslt.org/dates-and-times" extension-element-prefixes="ex">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no" xml:space="preserve"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="bg-def">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:transform>
Transformation result (Saxon 6.5.5 - Xslt 1.0):
<?xml version="1.0" encoding="UTF-8"?><OML>
<bg-def name="EX1"/>
</OML>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>