Creating a list using xslt - xslt

I have below XML
<?xml version="1.0" encoding="UTF-8"?>
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<FirstName>John</FirstName>
<LastName>Peter</LastName>
<Initial>T</Initial>
</Employee>
In XSLT 1.0 I want to write an XSLT to produce below XML from the xml above. can anyone help to me write this xslt?
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfstringVariable xmlns="http://schemas.abc.org/2004/07/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<stringVariable>
<name>FirstName</name>
<value>John</value>
</stringVariable>
<stringVariable>
<name>LastName</name>
<value>Peter</value>
</stringVariable>
<stringVariable>
<name>Initial</name>
<value>T</value>
</stringVariable>
</ArrayOfstringVariable>

Following XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="no"
encoding="UTF-8" indent="yes" />
<xsl:template match="Employee">
<ArrayOfstringVariable>
<xsl:apply-templates select="*"/>
</ArrayOfstringVariable>
</xsl:template>
<xsl:template match="*">
<stringVariable>
<name>
<xsl:value-of select="local-name()"/>
</name>
<value>
<xsl:value-of select="."/>
</value>
</stringVariable>
</xsl:template>
</xsl:stylesheet>
when applied to the example input XML from your question produces the following output:
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfstringVariable>
<stringVariable>
<name>FirstName</name>
<value>John</value>
</stringVariable>
<stringVariable>
<name>LastName</name>
<value>Peter</value>
</stringVariable>
<stringVariable>
<name>Initial</name>
<value>T</value>
</stringVariable>
</ArrayOfstringVariable>
In case you want to have the namespace in the output XML at the ArrayOfStringVariable element, this can be done with two adjustments: add xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" to the xsl:stylesheet declaration and adjust <ArrayOfstringVariable to <ArrayOfstringVariable xmlns="http://schemas.abc.org/2004/07/" > at the <xsl:template match="Employee"> and also adjust <stringVariable> to <stringVariable xmlns="http://schemas.abc.org/2004/07/"> at the <xsl:template match="*">.

Related

XSLT transformation validate XSI:type (or) element node exists

I have an input XML, which needs to be filtered if element node exists 'ns1:getGenResponse' (or) validate with xsi:type = "Gen" of 'multiRef' element
If either one of the condition successful then I can process 'multiRef' records.
Input XML:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<soapenv:Body>
<ns1:getGenResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://service.pen.eewe.en.de>
<ns1:getGenReturn xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:Array" soapenc:arrayType="xsd:anyType[2]">
<item href="#id0" />
<item href="#id1" />
</ns1:getGenReturn>
</ns1:getGenResponse>
<multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Gen">
<name xsi:type="xsd:string">ulm</name>
<mail xsi:type="xsd:string">ulm#gmail.com</mail>
</multiRef>
<multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:Gen">
<name xsi:type="xsd:string">ABC</name>
<mail xsi:type="xsd:string">abc#gmail.com</mail>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
Trying with node exist 'ns1:getGenResponse':
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:response="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
exclude-result-prefixes="soap response"
>
<!-- Output -->
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<getGenResponse>
<xsl:for-each select="//soap:Body[ns1:getGenResponse]/multiRef">
<getGenReturn>
<name>
<xsl:value-of select="name" />
</name>
<mail>
<xsl:value-of select="mail" />
</mail>
</getGenReturn>
</xsl:for-each>
</getGenResponse>
</xsl:template>
</xsl:stylesheet>
With this XSLT, I can generate blank . I can't able to generate my desire output.
I am also trying to validate the data with xsi:type of 'multiRef' element node
with below code, but I am unable to execute the XSLT
**Trying to validate with xsi:type ="Gen"**
<xsl:stylesheet version="1.0" xmlns:response="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="soap response">
<!-- Output -->
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<getGenResponse>
<xsl:for-each select="//soap:Body/multiRef[substring- after(#xsi:type, ':')='Gen']">
<getGenReturn>
<name><xsl:value-of select="name"/></name>
<mail><xsl:value-of select="mail"/></mail>
</getGenReturn>
</xsl:for-each>
</getGenResponse>
</xsl:template>
</xsl:stylesheet>
Output expects:
**Output Expected**
<?xml version="1.0" encoding="UTF-8"?>
<getGenResponse>
<getGenReturn>
<name> ULM </name>
<mail>ulm#gmail.com<mail>
</getGenReturn>
<getGenReturn>
<name>ABC</name>
<mail>abc#gmail.com<mail>
</getGenReturn>
/getGenResponse>
Thank you very much.
yes, I declared xmlns:ns1="http://service.pen.eewe.en.de" in the XSLT. now I am able to execute the code with desired result.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:response="http://tempuri.org/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
exclude-result-prefixes="soap response" xmlns:ns1="http://service.pen.eewe.en.de"
>
<!-- Output -->
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<getGenResponse>
<xsl:for-each select="//soap:Body[ns1:getGenResponse]/multiRef">
<getGenReturn>
<name>
<xsl:value-of select="name" />
</name>
<mail>
<xsl:value-of select="mail" />
</mail>
</getGenReturn>
</xsl:for-each>
</getGenResponse>
</xsl:template>
</xsl:stylesheet>

XSLT for-each-group from variable does not work

for-each-group from XSLT 2.0 works as expected from a file but not from a variable.
Have this file:
~$ cat test.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<delimiter/>
<c>A</c><c>B</c>
<delimiter/>
<c>C</c>
</root>
Using stylesheet for grouping this file:
<?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" version="1.0"
encoding="UTF-8" indent="yes" omit-xml-declaration="no" />
<xsl:template match="*">
<!-- variable not used for file test -->
<xsl:variable name="fields">
<root>
<delimiter/>
<c>A</c><c>B</c>
<delimiter/>
<c>C</c>
</root>
</xsl:variable>
<xsl:for-each-group select="*" group-starting-with="delimiter">
<field>
<xsl:for-each select="current-group()">
<xsl:value-of select="self::c"/>
</xsl:for-each>
</field>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
I get the result I want:
<?xml version="1.0" encoding="UTF-8"?>
<field>AB</field>
<field>C</field>
Trying to group the variable name="fields" with:
<xsl:for-each-group select="$fields/*" group-starting-with="delimiter">
I get the result:
<?xml version="1.0" encoding="UTF-8"?>
<field/>
Why does for-each-group works on a file but not from a variable?
The variable fields is a document-node(), you can define the type of the variable to be element()
<xsl:variable name="fields" as="element()">
<root>
<delimiter/>
<c>A</c><c>B</c>
<delimiter/>
<c>C</c>
</root>
</xsl:variable>

XSL to produce xml name value pair

I am using xslt 1.0 My input xml is as below
<?xml version="1.0" encoding="UTF-8"?>
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<FirstName>John</FirstName>
<LastName>Peter</LastName>
<Initial>T</Initial>
<Spouse>
<FirstName>Rita</FirstName>
<LastName>Hudson</LastName>
</Spouse>
</Employee>
I an trying to write a xsl to produce below output...
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfstringVariable xmlns="http://schemas.abc.org/2004/07/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<stringVariable>
<name>ServerName</name>
<value>tmn.eu.com</value>
</stringVariable>
<stringVariable>
<name>EmpFirstName</name>
<value>John</value>
</stringVariable>
<stringVariable>
<name>EmpLastName</name>
<value>Peter</value>
</stringVariable>
<stringVariable>
<name>SpouseFirstName</name>
<value>Rita</value>
</stringVariable>
<stringVariable>
<name>SpouseLastName</name>
<value>Hudson</value>
</stringVariable>
</ArrayOfstringVariable>
The output xml contains ArrayOfstringVariable stringVariable name value pair..
The name is hardcoded and the value is from input xml..
Name value "ServerName" is hardcoded.
I tried with xsl code below but it create name value pair with all the elements from input xml
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="no"
encoding="UTF-8" indent="yes" />
<xsl:template match="Employee">
<ArrayOfstringVariable>
<xsl:apply-templates select="*"/>
</ArrayOfstringVariable>
</xsl:template>
<xsl:template match="*">
<stringVariable>
<name>
<xsl:value-of select="local-name()"/>
</name>
<value>
<xsl:value-of select="."/>
</value>
</stringVariable>
</xsl:template>
</xsl:stylesheet>
Can anyone help me to write xsl to produce above output?
Thanks in advance
The XSLT will be straight forward as most of your elements are hardcoded:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ns="http://schemas.abc.org/2004/07/">
<xsl:output method="xml" omit-xml-declaration="no" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="Employee">
<ns:ArrayOfstringVariable>
<ns:stringVariable>
<ns:name>ServerName</ns:name>
<ns:value>tmn.eu.com</ns:value>
</ns:stringVariable>
<ns:stringVariable>
<ns:name>EmpFirstName</ns:name>
<ns:value>
<xsl:value-of select="FirstName"/>
</ns:value>
</ns:stringVariable>
<ns:stringVariable>
<ns:name>EmpLastName</ns:name>
<ns:value>
<xsl:value-of select="LastName"/>
</ns:value>
</ns:stringVariable>
<ns:stringVariable>
<ns:name>SpouseFirstName</ns:name>
<ns:value>
<xsl:value-of select="Spouse/FirstName"/>
</ns:value>
</ns:stringVariable>
<ns:stringVariable>
<ns:name>SpouseLastName</ns:name>
<ns:value>
<xsl:value-of select="Spouse/LastName"/>
</ns:value>
</ns:stringVariable>
</ns:ArrayOfstringVariable>
</xsl:template>
</xsl:stylesheet>

XML manipulation. 2 Input source XML

I have got 2 source to the XSLT, which needs to be mapped to the target. Have given below the source and desired output. The first source XML is in a collection which needs to be iterated to fetch the value.
Input Payload:
XML 1:
<ParticipentsCollection>
<Participents>
<Email>PM#y.com</Email>
<Role>PM</Role>
</Participents>
<Participents>
<Email>BM#y.com</Email>
<Role>BM</Role>
</Participents>
<Participents>
<Email>CM#y.com</Email>
<Role>CM</Role>
</Participents>
</ParticipentsCollection>
XML 2:
<Project>
<ID>1</ID>
<Name>XYZ</Name>
<Status>Req Gathering</Status>
</Project>
Desired Output:
<ProjectDetails>
<ID>1</ID>
<Name>XYZ</Name>
<Status>Req Gathering</Status>
<PM>PM#y.com</PM>
<BM>PM#y.com</BM>
<CM>>CM#y.com</CM>
</ProjectDetails>
If you are using XSLT 1.0 use:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="exslt msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="Doc2"><xsl:copy><xsl:copy-of select="document('Untitled2.xml')/Project"></xsl:copy-of></xsl:copy></xsl:param>
<xsl:template match="ParticipentsCollection">
<ProjectDetails>
<xsl:copy-of select="exslt:node-set($Doc2)/Project/*"/>
<xsl:for-each select="Participents">
<xsl:element name="{Role}"><xsl:value-of select="Email"/></xsl:element>
</xsl:for-each>
</ProjectDetails>
</xsl:template>
</xsl:stylesheet>
and if 2.0 use:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="Doc2"><xsl:copy><xsl:copy-of select="document('Untitled2.xml')/Project"></xsl:copy-of></xsl:copy></xsl:param>
<xsl:template match="ParticipentsCollection">
<ProjectDetails>
<xsl:copy-of select="$Doc2/Project/*"/>
<xsl:for-each select="Participents">
<xsl:element name="{Role}"><xsl:value-of select="Email"/></xsl:element>
</xsl:for-each>
</ProjectDetails>
</xsl:template>
</xsl:stylesheet>
I am running this XSLT on XML1 and keeping XML2 in $Doc2 param to get output:
<ProjectDetails>
<ID>1</ID>
<Name>XYZ</Name>
<Status>Req Gathering</Status>
<PM>PM#y.com</PM>
<BM>BM#y.com</BM>
<CM>CM#y.com</CM>
</ProjectDetails>

XSLT with namespaces: Copy template omits attributes

Applying the standard XSLT copy template,
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
to the JBoss AS 7 standalone.xml, leads to loss of parameters:
<?xml version="1.0" encoding="UTF-8"?><server xmlns="urn:jboss:domain:1.1">
<extensions>
<extension/>
<extension/>
instead of
<?xml version="1.0" encoding="UTF-8"?><server xmlns="urn:jboss:domain:1.1">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
<extension module="org.jboss.as.configadmin"/>
Why?
How can i Make it copy everything?
XSLT transformation is done by Maven XML plugin.
The whole template:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ds="urn:jboss:domain:datasources:1.0"
xmlns="urn:jboss:domain:1.1"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*|#*|node()">
<xsl:copy>
<xsl:apply-templates select="*|#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Your template appears to be working correctly.
I modified it and the XML to show that is working:
<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="urn:jboss:domain:1.1">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
<extension module="org.jboss.as.configadmin"/>
</extensions>
</server>
Run with this XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ds="urn:jboss:domain:datasources:1.0"
xmlns:so="urn:jboss:domain:1.1"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*|#*|node()">
<xsl:copy>
<xsl:apply-templates select="*|#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="so:extension">
<xsl:copy>
<xsl:attribute name="testing">just for fun!!</xsl:attribute>
<xsl:copy-of select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Produces:
<?xml version="1.0"?>
<server xmlns="urn:jboss:domain:1.1">
<extensions>
<extension testing="just for fun!!" module="org.jboss.as.clustering.infinispan"/>
<extension testing="just for fun!!" module="org.jboss.as.configadmin"/>
</extensions>
</server>
Here's the output run with your original XSL:
<?xml version="1.0"?>
<server xmlns="urn:jboss:domain:1.1">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
<extension module="org.jboss.as.configadmin"/>
</extensions>
</server>
I downloaded the full JBoss standalone.xml, ran your XSL, and here's the diff of the input and output XML:
so zacharyyoung$ xsltproc so.xsl so.xml > output.xml
so zacharyyoung$ diff so.xml output.xml
1,2c1
< <?xml version='1.0' encoding='UTF-8'?>
<
---
> <?xml version="1.0"?>