I am writing an xslt transformation for below XLS code:
<?xml version="1.0"?>
<OTA_HotelPmsInfoNotif xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" EchoToken="PMS" Version="0.101" PrimaryLangID="en" ClosureDate="2020-10-29" RetransmissionIndicator="true" SequenceNmbr="2" TimeStamp="2020-10-29T23:51:00Z">
<POS>
<Source>
<RequestorID Type="81" ID="POF" ID_Context="parol"/>
</Source>
<Source ISOCountry="CZ" ISOCurrency="CZE">
<RequestorID Type="10" ID="H1111" ID_Context="star">
<CompanyName>Pharmacy Prague</CompanyName>
</RequestorID>
</Source>
</POS>
</OTA_HotelPmsInfoNotif>
I would like to pull out of this XML attribute named ID but as you can see there are two ID attributes, ID="POF" and ID = "H1111". As for now i have what follows:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:text>RID</xsl:text>
<xsl:text>
</xsl:text>
<xsl:for-each select="OTA_HotelPmsInfoNotif/POS/Source/RequestorID">
<xsl:text>"</xsl:text>
<xsl:if test ="#ID='H1111'">
<xsl:value-of select="#ID"/>
</xsl:if>
<xsl:text>";"</xsl:text>
<xsl:text>"</xsl:text>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
But this code enters one empty line for ID="POF". How to extract only one atrribute ID="H1111"?
If you know the value of the Type attribute, you can do simply:
<xsl:value-of select="OTA_HotelPmsInfoNotif/POS/Source/RequestorID[#Type='10']/#ID"/>
Demo: https://xsltfiddle.liberty-development.net/aiyndY
Related
I am trying to transform the following XML using XSLT
<?xml version="1.0" encoding="UTF-8"?>
<root>
<CandidateId>863</CandidateId>
<CaseId>2762833</CaseId>
<Status>Completed</Status>
<InitiatedDate>01 Dec 2022</InitiatedDate>
<CompletionDate>15 Jan 2022</CompletionDate>
<Comments />
</root>
My XSLT code is as follows:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/">
<JobApplication>
<xsl:for-each select="root">
<JobApplication>
<xsl:variable name="month" select="substring(InitiatedDate,4,3)" />
<xsl:if test="$month = 'Dec'">
<xsl:variable name="m">12</xsl:variable>
</xsl:if>
<xsl:if test="$month = 'Nov'">
<xsl:variable name="m">11</xsl:variable>
</xsl:if>
<xsl:if test="$month = 'Oct'">
<xsl:variable name="m">10</xsl:variable>
</xsl:if>
<Bbgvdate><xsl:value-of select="concat(substring(InitiatedDate,8,4),'-',$m,'-',substring(InitiatedDate,1,2),'T00:00:00')"/></Bbgvdate>
<applicationId><xsl:value-of select="CandidateID"/></applicationId>
</JobApplication>
</xsl:for-each>
</JobApplication>
</xsl:template>
</xsl:stylesheet>
Now, I am unable to call the variable "m" for some reason in "Bbgvdate"
I am looking for a converted date that looks like "2022-12-15" (in yyyy-mm-dd format)
I get the error:
Unable to generate the XML document using the provided XML/XSL input. Errors were reported during stylesheet compilation
Need help with this.
Thanks
I have XML in the following format:
<?xml version="1.0"?>
<MES_VEHICLE_STATUS_DESCRIPTOR xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="MOM.Production" PRODUCTIONORDER="000001995795" >
<POSECTION LOCATION="" />
<ORDERSECTION SALESORDER="" />
<MATERIALCONSUMPTIONSECTION>
<MATERIAL_CONSUMPTION DESC="car" QTY="1.000" WORKPLACE="3001_GAT101LH">BIN1000004</MATERIAL_CONSUMPTION>
<MATERIAL_CONSUMPTION DESC="PLAIN_WASHER" QTY="1.000" WORKPLACE="3001_GAT101LH">WRE20000018</MATERIAL_CONSUMPTION>
<MATERIAL_CONSUMPTION DESC="car" QTY="1.000" WORKPLACE="3001_GAT101LH">BIN1000003</MATERIAL_CONSUMPTION>
</MATERIALCONSUMPTIONSECTION>
</MES_VEHICLE_STATUS_DESCRIPTOR>
and output should look like that:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:mat="http://mes.com/ScrapManagement">
<soapenv:Header/>
<soapenv:Body>
<mat:DT_SCRAPMANAGEMENT_MES_REQ>
<DATA>
<PlantCode>3002</PlantCode>
<SAPOrder>000001995795</SAPOrder>
<Quantity>1.000</Quantity>
<PartNo>BIN1000004</PartNo>
<WorkPlace>3001_GAT101LH</WorkPlace>
</DATA>
<DATA>
<PlantCode>3002</PlantCode>
<SAPOrder>000001995795</SAPOrder>
<Quantity>1.000</Quantity>
<PartNo>WRE20000018</PartNo>
<WorkPlace>3001_GAT101LH</WorkPlace>
</DATA>
<DATA>
<PlantCode>3002</PlantCode>
<SAPOrder>000001995795</SAPOrder>
<Quantity>1.000</Quantity>
<PartNo>BIN1000003</PartNo>
<WorkPlace>3001_GAT101LH</WorkPlace>
</DATA>
</mat:DT_SCRAPMANAGEMENT_MES_REQ>
</soapenv:Body>
</soapenv:Envelope>
My XSLT to transform
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" />
<xsl:template match="MES_VEHICLE_STATUS_DESCRIPTOR">
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:mat="http://mes.com/ScrapManagement">
<soapenv:Header />
<soapenv:Body>
<xsl:element name="mat:DT_SCRAPMANAGEMENT_MES_REQ">
<xsl:variable name="po" select="#PRODUCTIONORDER" />
<xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION">
<DATA>
<PlantCode>
<xsl:text>3002</xsl:text>
</PlantCode>
<SAPOrder>
<xsl:value-of select="$po" />
</SAPOrder>
<Quantity>
<xsl:value-of select="#QTY" />
</Quantity>
<PartNo>
<xsl:value-of select="." />
</PartNo>
<WorkPlace>
<xsl:value-of select="#WORKPLACE" />
</WorkPlace>
</DATA>
</xsl:for-each>
</xsl:element>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
If i delete xmlns="MOM.Production" in XML file, the transformation is OK. But if have it in xml file, cannot transform. I use website: https://www.online-toolz.com/tools/xslt-transformation.php and show the error: Error:DOMDocument::loadXML(): xmlns: URI MOM.Production is not absolute in Entity, line: 2.
I don't understand what is reason.
I don't understand what is reason
The code you had in mind is probably more or less this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" />
<xsl:template match="MES_VEHICLE_STATUS_DESCRIPTOR">
<xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION">
<xsl:element name="DATA">
<xsl:element name="PRODUCTIONORDER">
<xsl:value-of select="../../#PRODUCTIONORDER" />
</xsl:element>
<xsl:element name="QTY">
<xsl:value-of select="#QTY" />
</xsl:element>
<xsl:element name="MATERIAL">
<xsl:value-of select="text()" />
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I think you have to understand the difference between relative and absolute paths in the XPATH expressions your are using to select the correct nodes.
When you are inside a template matching the node MES_VEHICLE_STATUS_DESCRIPTOR, you don't use absolute paths like /MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION (which doesn't exist in this case), but paths relative to this node, as MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION.
When you are inside a <xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION"> loop, you have to select the nodes with relative paths like text(), ../../#PRODUCTIONORDER or #QTY. Notice the # telling the QTY and PRODUCTIONORDER are attribute type nodes.
Finally, your current output is no well formed XML since it lacks a root element.
Personnaly, I would replace the <xsl:element> tag by its litteral value and avoid the computation of a constant field accross a loop:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" />
<xsl:template match="MES_VEHICLE_STATUS_DESCRIPTOR">
<xsl:variable name="po" select="#PRODUCTIONORDER" />
<xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION">
<DATA>
<PRODUCTIONORDER><xsl:value-of select="$po" /></PRODUCTIONORDER>
<QTY><xsl:value-of select="#QTY" /></QTY>
<MATERIAL><xsl:value-of select="." /></MATERIAL>
</DATA>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I'm using XSL to create a PDF document template, and don't want certain fields to display if the line value is zero.
I have tried
<xsl:if test="line_value != 0">
<xsl:with-param name="value" select="unit_quantity"/>
</xsl:if>
But this doesn't work. I think because line_value is of the format £0.00.
I'm trying to get it to do line_value NOT LIKE '£0.00', but I don't think that's the correct syntax for XSL.
I am assuming that below is your XML:
INPUT:
<?xml version="1.0" encoding="utf-8" ?>
<body>
<line_value>£0.00</line_value>
<line_value>£1.00</line_value>
<line_value>£0.00</line_value>
<line_value>£2.00</line_value>
<line_value>£0.00</line_value>
<line_value>£5.00</line_value>
<line_value>£0.00</line_value>
<line_value>£1.00</line_value>
</body>
XSLT:
<?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" exclude-result-prefixes="xs" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:for-each select="body/line_value">
<xsl:if test="number(translate(., '£', '')) != 0">
<num>
<xsl:value-of select="."/>
</num>
</xsl:if>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
I have a soap xml output and need to convert it to plain text file. I am trying to use xsltproc. Got the following xsl tempalate online
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:csv="csv:csv">
<xsl:output method="text" encoding="utf-8" />
<xsl:strip-space elements="*" />
<xsl:variable name="delimiter" select="'|'" />
<csv:columns><column>Numbers</column></csv:columns>
<xsl:template match="getNumbersResponse">
<xsl:variable name="property" select="." />
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
My soap xml output is as follows
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body>
<ns4:getNumbersResponse xmlns:ns4="http://service.engine.com"><ns4:Numbers>100</ns4:Numbers>
<ns4:Numbers>200</ns4:Numbers>
</ns4:getNumbersResponse>
</soapenv:Body>
</soapenv:Envelope>
When I try xsltproc using the above xsl tempalate to transform this xml output, I get records in following format
100200
I want to add a new line between each record. Found online that adding following line should do it but I do not see any changes in the output with or without this line in xsl template.
<xsl:text>
</xsl:text>
I would want my output to be like this
Numbers|
100|
200|
Your stylesheet doesn't actually do anything, because your only template does not match anything in the source XML. The output you see is purely the result of the built-in template rules.
If you want to get a return-separated list of the ns4:Numbers values, you should do:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns4="http://service.engine.com">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="/soapenv:Envelope">
<xsl:for-each select="soapenv:Body/ns4:getNumbersResponse/ns4:Numbers">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Note the use of declared prefixes to address the nodes in your XML.
To get the result in your edited question, do:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns4="http://service.engine.com">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="/soapenv:Envelope">
<xsl:text>Numbers|
</xsl:text>
<xsl:for-each select="soapenv:Body/ns4:getNumbersResponse/ns4:Numbers">
<xsl:value-of select="."/>
<xsl:text>|
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
i have input xml as
<content>
<date>
<day>14</day>
<month>06</month>
<year>2012</year>
</date>
</content>
want it to be converted into
<content>
<date>2012-06-14T00:00:00</date>
</content>
xslt used
<?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="content">
<content>
<xsl:apply-templates select="date"/>
</content>
</xsl:template>
<xsl:template match="date">
<date>
<xsl:variable name="year" select="year"/>
<xsl:variable name="month" select="month"/>
<xsl:variable name="day" select="day"/>
<xsl:value-of select="$year" />-<xsl:value-of select="$month"/>-
<xsl:value-of select="$day"/>
</date>
</xsl:template>
</xsl:stylesheet>
i want date in YYYYMMDDTHH:MM:SS format as example 2012-06-15T02:52:37 how can i get it.Which function in xslt "1.0" pics the strings and take the format pattern as such. Can aynone please help me in getting the above format.
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:template match="/*">
<content>
<xsl:apply-templates/>
</content>
</xsl:template>
<xsl:template match="date">
<date>
<xsl:value-of select="concat(year, '-', month, '-', day, 'T00:00:00')"/>
</date>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<content>
<date>
<day>14</day>
<month>06</month>
<year>2012</year>
</date>
</content>
produces the wanted, correct result:
<content>
<date>2012-06-14T00:00:00</date>
</content>