I'm calling in XML using document(). I need to transform the imported XML. Is this possible?
<xsl:copy-of select="document('C:\my.xml')/*"/>
<xsl:apply-templates/>
Thanks!
Use <xsl:apply-templates select="document('file:///c:/my.xml')/*"/>, then you only need to add templates for the nodes in the file.
For example, a my.xml is given below
<?xml version="1.0" standalone="no"?>
<root>
<a>XXX</a>
<b>YYY</b>
</root>
and the current xml is given below:
<?xml version="1.0" encoding="UTF-8"?>
<root_test>
<test1>123</test1>
<test2>456</test2>
</root_test>
when the following stylesheet is applied:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="root_test">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="document('my.xml')/*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[document('my.xml')]">
<success><xsl:apply-templates/></success>
</xsl:template>
</xsl:stylesheet>
it outputs
<?xml version="1.0" encoding="utf-8"?>
<root_test>
123
456
<success>XXX</success>
YYY
</root_test>
notice that the templates for node a in my.xml has been applied.
Related
I want to create an xslt(version 2) where value can be split with delimeter ':' and print only first part of split and store the second part into a variable. The values have to be passed to a 'student' tag. Following are the values that are fetched from db
Adam:101
Brad:110
Chad:111
Expected output:
Adam
Brad
Chad
and values 101, 110 and 111 have to stored into a variable.
Please also provide a link where xslt2.0 tutorial is available in detail.
Simply you can use fn:tokenize() to achieve the output:
Assume input:
<student>Adam:101 Brad:110 Chad:111</student>
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="#all"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<students>
<xsl:apply-templates/>
</students>
</xsl:template>
<xsl:template match="student">
<xsl:for-each select="tokenize(., ' ')">
<student variable="{substring-after(., ':')}">
<xsl:value-of select="substring-before(., ':')"/>
</student>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
OUTPUT:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student variable="101">Adam</student>
<student variable="110">Brad</student>
<student variable="111">Chad</student>
</students>
Link: https://xsltfiddle.liberty-development.net/gVrvcxx
I am trying remove blank lines without stripping spaces and indentation, because my requirement is indented XML. Can anyone help me, please?
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<Export>
<bio id="b0001">
<p>Maciej</p>
</bio>
<funding-group>
<award-group>
<funding-source>
<named-content content-type="funder-name">Narodowe</named-content>
<named-content content-type="funderidentifier">501100004281</named-content>
</funding-source>
<award-id>/19/B/HS4/</award-id>
<award-id>3</award-id>
</award-group>
</funding-group>
</Export>
Expected Result
<?xml version="1.0" encoding="UTF-8"?>
<Export>
<bio id="b0001">
<p>Maciej</p>
</bio>
<funding-group>
<award-group>
<funding-source>
<named-content content-type="funder-name">Narodowe Centrum Nauki</named-content>
<named-content content-type="funderidentifier">10.13039/501100004281</named-content>
</funding-source>
<award-id>/19/B/HS4/</award-id>
<award-id>3</award-id>
</award-group>
</funding-group>
</Export>
XSLT I have tried this xsl but it's not worked properly if i have run this xsl then generate XML single line.
<?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="2.0">
<xsl:output method="xml" omit-xml-declaration="no"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//text()">
<xsl:value-of select="translate(.,'
', '')"/>
</xsl:template>
</xsl:stylesheet>
I have an XML with some mixed Nodes,and I want to get just the value of the parent and not the child.
My XML
<?xml version="1.0" encoding="UTF-8"?>
<Records>
<DET>
<detnumber>100126</detnumber>
<EmployeeNo>100126</EmployeeNo>
<action>CHANGE</action>
<first_name> NewHire-4th
<previous>NewHire</previous>
</first_name>
<last_name>Test-Changed 4th
<previous>Test-Changed 3rd</previous>
</last_name>
<birth_name>
NewHire-Changed 4th
<previous>NewHire-Changed 3rd</previous>
</birth_name>
<formal_name>
NewHire-4th Test-Changed 4th
<previous>NewHire Test-Changed 3rd</previous>
</formal_name>
<salutation>
MISS
<previous>MRS</previous>
</salutation>
<email_address>
testHire4#gmail.com
<previous>testHire2#gmail.com</previous>
</email_address>
</DET>
</Records>
Using XSLT 2.0 ,
I am mostly using copy of in my xslt, But the whole Node and its child are being copied. I need to be able to restrict only to the parent.
<xsl:copy-of select="first_name"/>
<xsl:copy-of select="last_name"/>
<xsl:copy-of select="birth_name"/>
<xsl:copy-of select="formal_name"/>
<xsl:copy-of select="salutation"/>
Below is my preferred output
<?xml version="1.0" encoding="UTF-8"?>
<Records>
<DET>
<detnumber>100126</detnumber>
<EmployeeNo>100126</EmployeeNo>
<action>CHANGE</action>
<first_name> NewHire-4th</first_name>
<last_name>Test-Changed 4th</last_name>
<birth_name>NewHire-Changed 4th</birth_name>
<formal_name>NewHire-4th Test-Changed 4th</formal_name>
<salutation>MISS</salutation>
<email_address>testHire4#gmail.com</email_address>
</DET>
</Records>
Check this Code:-
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="previous"/>
</xsl:stylesheet>
I am attempting to write an XSLT stylesheet that removes the milliseconds from any timestamp in an XML form. My sample XML below is just a sample there could conceivably be any number of timestamps in the envelope. So I'm thinking I need to pattern match the timestamp and then transform it. I can use XSLT 2.0 The original message looks like:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
</soap:Header>
<soap:Body>
<Staging_Submit_Service xmlns="com.xxx">
<u_From_Partner__c>Our Partner</u_From_Partner__c>
<u_To_Partner__c>Us</u_To_Partner__c>
<u_Partner_CI__c/>
<u_Partner_ID__c>10051</u_Partner_ID__c>
<u_Partner_Name__c>ROSEVILLE</u_Partner_Name__c>
<u_Partner_Reported_Date__c>2016-07-26T17:38:28.746134Z</u_Partner_Reported_Date__c>
<u_Partner_Status_Reason__c>Failure in System</u_Partner_Status_Reason__c>
<u_Partner_Submit_Date__c>2016-07-25T18:11:23.5443Z</u_Partner_Submit_Date__c>
<u_Partner_Priority__c>Low</u_Partner_Priority__c>
<u_Partner_Service_Type>Event</u_Partner_Service_Type>
</Staging_Submit_Service>
</soap:Body>
</soap:Envelope>
and my resulting xml needs to look like:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
</soap:Header><soap:Body>
<Staging_Submit_Service xmlns="com.xxx">
<u_From_Partner__c>Our Partner</u_From_Partner__c>
<u_To_Partner__c>Us</u_To_Partner__c>
<u_Partner_CI__c/>
<u_Partner_ID__c>10051</u_Partner_ID__c>
<u_Partner_Name__c>ROSEVILLE</u_Partner_Name__c>
<u_Partner_Reported_Date__c>2016-07-26T17:38:28Z</u_Partner_Reported_Date__c>
<u_Partner_Status_Reason__c>Failure in System</u_Partner_Status_Reason__c>
<u_Partner_Submit_Date__c>2016-07-25T18:11:23Z</u_Partner_Submit_Date__c>
<u_Partner_Priority__c>Low</u_Partner_Priority__c>
<u_Partner_Service_Type>Event</u_Partner_Service_Type>
</Staging_Submit_Service>
</soap:Body>
</soap:Envelope>
Notice the timestamps. I started down this path but it doesn't seem to be getting me where I need to be.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="java:com.verizon.webservices.adapter.clecclient">
<xsl:output method="xml" indent="no" version="1.0" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="#*|node()"
<xsl:copy>
<xsl:value-of select="." />
<xsl:value-of select='matches(.,".*[0-9]\{4\}-[0-9]\{2\}.*:[0-9]\{2\}*")'/>
<xsl:value-of select='replace(., "s/.*[0-9]\{4\}-[0-9]\{2\}.*:[0-9]\{2\}\(\.[0-9]*\).*/\1","")'/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I am really only vaguely familiar with XSLT and this particular problem requires me to use it.
From the comments it seems that you can only use an XSLT 1.0 solution.
Here is one:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:df="com.xxx">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="df:u_Partner_Reported_Date__c/text()
|df:u_Partner_Submit_Date__c/text()">
<xsl:value-of select="concat(substring-before(.,'.'), 'Z')"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
</soap:Header>
<soap:Body>
<Staging_Submit_Service xmlns="com.xxx">
<u_From_Partner__c>Our Partner</u_From_Partner__c>
<u_To_Partner__c>Us</u_To_Partner__c>
<u_Partner_CI__c/>
<u_Partner_ID__c>10051</u_Partner_ID__c>
<u_Partner_Name__c>ROSEVILLE</u_Partner_Name__c>
<u_Partner_Reported_Date__c>2016-07-26T17:38:28.746134Z</u_Partner_Reported_Date__c>
<u_Partner_Status_Reason__c>Failure in System</u_Partner_Status_Reason__c>
<u_Partner_Submit_Date__c>2016-07-25T18:11:23.5443Z</u_Partner_Submit_Date__c>
<u_Partner_Priority__c>Low</u_Partner_Priority__c>
<u_Partner_Service_Type>Event</u_Partner_Service_Type>
</Staging_Submit_Service>
</soap:Body>
</soap:Envelope>
the wanted, correct result is produced:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
</soap:Header>
<soap:Body>
<Staging_Submit_Service xmlns="com.xxx">
<u_From_Partner__c>Our Partner</u_From_Partner__c>
<u_To_Partner__c>Us</u_To_Partner__c>
<u_Partner_CI__c/>
<u_Partner_ID__c>10051</u_Partner_ID__c>
<u_Partner_Name__c>ROSEVILLE</u_Partner_Name__c>
<u_Partner_Reported_Date__c>2016-07-26T17:38:28Z</u_Partner_Reported_Date__c>
<u_Partner_Status_Reason__c>Failure in System</u_Partner_Status_Reason__c>
<u_Partner_Submit_Date__c>2016-07-25T18:11:23Z</u_Partner_Submit_Date__c>
<u_Partner_Priority__c>Low</u_Partner_Priority__c>
<u_Partner_Service_Type>Event</u_Partner_Service_Type>
</Staging_Submit_Service>
</soap:Body>
</soap:Envelope>
Try
<xsl:template match="*[not(*) and . castable as xs:dateTime]">
<xsl:copy>
<xsl:value-of select="format-dateTime(., '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01]')"/>
</xsl:copy>
</xsl:template>
plus your first template.
So the complete stylesheet is
<?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="2.0">
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*) and . castable as xs:dateTime]">
<xsl:copy>
<xsl:value-of select="format-dateTime(., '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01]')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Actually the above seems to not preserve any timezone suffix present and ensuring it is output as Z if it is UTC is a bit tricky, but I think if you make the value-of
<xsl:value-of select="if (timezone-from-dateTime(.) eq xs:dayTimeDuration('PT0H')) then format-dateTime(., '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01]Z') else format-dateTime(., '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01][Z]')"/>
then it works fine.
It seems the problem about the timezone Z was resolved in https://www.w3.org/TR/xpath-functions-31/#rules-for-datetime-formatting to allow
<xsl:value-of select="format-dateTime(., '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01][Z00:00t]')"/>
but I have not tested whether that works with XmlPrime or processors other than Saxon.
The following works for me with Xalan inside Oxygen as far as identifying the two elements with dateTimes in your input sample and reformatting them to remove the decimals of the seconds:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:date="http://exslt.org/dates-and-times"
exclude-result-prefixes="xs date" version="1.0">
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*) and string-length() > 19 and date:date() != '']">
<xsl:copy>
<xsl:value-of select="date:format-date(date:date(.), "yyyy-MM-dd'T'HH:mm:ssZ")"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
However the created output dates differ, the input <u_Partner_Reported_Date__c>2016-07-26T17:38:28.746134Z</u_Partner_Reported_Date__c> shows up as <u_Partner_Reported_Date__c>2016-07-25T22:00:00+0000</u_Partner_Reported_Date__c>, so either the date parsing or formatting is broken.
I have a style sheet like this
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="testParam"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="resources/integer[#name='LOG_LEVEL']/text()">
<xsl:value-of select="$testParam"/>
</xsl:template>
</xsl:stylesheet>
And I have an input xml like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="LOG_LEVEL">3</integer>
<string name="app_name">Test Application</string>
</resources>
But when I try to call an xslt transform in ant using this:
<xslt in="in.xml" out="out.xml" style="style_above.xsl">
<outputproperty name="method" value="xml"/>
<outputproperty name="encoding" value="UTF-8"/>
<outputproperty name="indent" value="yes"/>
<param name="testParam" expression="test"/>
</xslt>
I get the following:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<integer name="LOG_LEVEL"/>
<string name="app_name">Test Application</string>
</resources>
it doesn't seem to be changing my xslt parameter to the value I specify in my ant target
Yep, i figured out the problem was a different thing. Was about to update this was too late. I defined the xslt task in a macro and have a optional element also named param and that was the culprit. Thanks