XSLT to remove elements from xml - xslt

I have a following xml.
<?xml version="1.0" encoding="windows-1252"?>
<Person>
<Header>
<Header>1</Header>
</Header>
<Details Id="2">
<First>GERRARD</First>
<Last>STEVE1 </Last>
</Details>
<Details Id="3">
<First>GERRARD</First>
<Last>STEVE2 </Last>
</Details>
<Details Id="3">
<First>GERRARD</First>
<Last>STEVE3 </Last>
</Details>
<Footer>
<Footer>liverpool</Footer>
</Footer>
</Person>
I need to delete the Details element and generate another xml which looks as follows
<?xml version="1.0" encoding="windows-1252"?>
<Person>
<Header>
<Header>1</Header>
</Header>
<Footer>
<Footer>liverpool</Footer>
</Footer>
</Person>
Thanks in advance.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Details"/>
</xsl:stylesheet>

Related

change element name with attribute value using XSLT

I want to change element name with attribute value
My input xml looks like below
<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<ROW id="1">
<D n="ord_code">10033</D>
<D n="po_commts">Part and Service Requisition Example</D>
<D n="createddt">2021-02-11 00:00:00.0</createddt>
</ROW>
<ROW id="2">
<D n="ord_code">10018</D>
<D n="po_commts">GL Test</D>
<D n="createddt">2021-02-04 00:00:00.0</D>
</ROW>
</Envelope>
my expected result child element name replaced with attribute value
<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<ROW id="1">
<ord_code>10033</ord_code>
<po_commts>Part and Service Requisition Example</po_commts>
<createddt>2021-02-11 00:00:00.0</createddt>
</ROW>
<ROW id="2">
<ord_code>10018</ord_code>
<po_commts>GL Test</po_commts>
<createddt>2021-02-04 00:00:00.0</createddt>
</ROW>
</Envelope>
Here's how you could do it:
<?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" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="D">
<xsl:element name="{#n}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
See it working here : https://xsltfiddle.liberty-development.net/gVrvcy2

XSLT code to pass a value in output XML based on a condition in input XML

Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<DATA>
<RECORDS>
<Group>
<Name>12345</Name>
<Grp>MANAGER</Grp>
<FName>Alex</FName>
<LName>Johnson</LName>
<String1>abcd</String1>
/Group>
<Group>
<Name>67891</Name>
<Grp>PROJECT MANAGER</Grp>
<FName>JAMES</FName>
<LName>HARPER</LName>
<String1></String1>
</Group> </RECORDS> <LOGIN>
<User>
<Name>12345</UserName>
<Last>14/02/2013</Last>
</User>
<User>
<Name>67891</Name>
<Last>14/01/2013/Last>
</User> </LOGIN> </DATA>
Requirement:
In output XML
If String1 has a value then Type tag should have value as "axbx" and
if String1 is blank then Type tag should have value as "dydy"
<?xml version="1.0" encoding="UTF-8"?>
<DATA>
<RECORDS>
<Group>
<Name>12345</Name>
<Grp>MANAGER</Grp>
<FName>Alex</FName>
<LName>Johnson</LName>
<Type>axbx</Type>
</Group>
<Group>
<Name>67891</Name>
<Grp>PROJECT MANAGER</Grp>
<FName>JAMES</FName>
<LName>HARPER</LName>
<Type>dydy</Type>
</Group> </RECORDS> </DATA>
Please suggest.
I can't edit your question so I copy the corrected XML:
<?xml version="1.0" encoding="UTF-8"?>
<DATA>
<RECORDS>
<Group>
<Name>12345</Name>
<Grp>MANAGER</Grp>
<FName>Alex</FName>
<LName>Johnson</LName>
<String1>abcd</String1>
</Group>
<Group>
<Name>67891</Name>
<Grp>PROJECT MANAGER</Grp>
<FName>JAMES</FName>
<LName>HARPER</LName>
<String1></String1>
</Group>
</RECORDS>
<LOGIN>
<User>
<Name>12345</Name>
<Last>14/02/2013</Last>
</User>
<User>
<Name>67891</Name>
<Last>14/01/2013</Last>
</User>
</LOGIN>
</DATA>
and the XSL
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="String1">
<Type>
<xsl:choose>
<xsl:when test="string-length(.) > 0">axbx</xsl:when>
<xsl:otherwise>dydy</xsl:otherwise>
</xsl:choose>
</Type>
</xsl:template>
</xsl:stylesheet>
I'm not very experienced so there might be a better way.

Importing OAI source into Filemaker

I have a problem with importing an OAI source into Filemaker. The mapping is ok but the result is empty.
This is the source:
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://dublincore.org/documents/dcmi-namespace/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<responseDate>2015-01-15T12:05:11Z</responseDate>
<request verb="ListRecords" metadataPrefix="oai_dc">
http://api.memorix-maior.nl/collectiebeheer/oai-pmh/key/SORRY_THIS_KEY_I_CANNOT_SHOW/tenant/nfm
</request>
<ListRecords>
<record>
<header>
<identifier>
e:1d59bf74-a57c-11e1-af90-bf6f69fae6b6:000a80bf-e7d6-7670-b2bd-c269b2e58878
</identifier>
etc.
And this is the xslt I made:
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<ERRORCODE>0</ERRORCODE>
<METADATA>
<FIELD NAME="identifier" TYPE="TEXT"/>
</METADATA>
<RESULTSET>
<xsl:for-each select="OAI-PMH/ListRecords/record">
<ROW>
<COL>
<DATA><xsl:value-of select="header/identifier"/></DATA>
</COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>
To make it clear I only pointed the first field in the OAI source.
I hope you can help me to fix this.
Best regards,
Boudewijn Ridder
The reason why your attempt doesn't work is that the source XML nodes are in a namespace. You must declare this namespace in your stylesheet, assign it a prefix and use that prefix when addressing the nodes:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:oai="http://www.openarchives.org/OAI/2.0/">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<METADATA>
<FIELD NAME="identifier" TYPE="TEXT"/>
</METADATA>
<RESULTSET>
<xsl:for-each select="oai:OAI-PMH/oai:ListRecords/oai:record">
<ROW>
<COL>
<DATA><xsl:value-of select="oai:header/oai:identifier"/></DATA>
</COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>
Note:
If your input example is representative, you might want to use :
<xsl:value-of select="normalize-space(oai:header/oai:identifier)"/>
to trim the extraneous whitespace from the result.

Select value of element which is referenced by other

I have (this is an example) the following xml:
<?xml version="1.0" encoding="UTF-8"?>
<body>
<list>
<toot id="1">
<value>A</value>
</toot>
<toot id="2">
<value>B</value>
</toot>
<toot id="3">
<value>C</value>
</toot>
<toot id="4">
<value>D</value>
</toot>
</list>
<otherlist>
<foo>
<value ref="2" />
</foo>
<foo>
<value ref="3" />
</foo>
</otherlist>
</body>
And the following XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/body">
<xsl:apply-templates select="otherlist"/>
</xsl:template>
<xsl:template match="otherlist">
<xsl:for-each select="foo">
<result>
<value><xsl:value-of select="/body/list/toot[#id=value/#ref]/value" /></value><!-- This is the important -->
<ref><xsl:value-of select="value/#ref" /></ref>
</result>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
And this is the result when it make/transform the xml:
<?xml version="1.0" encoding="UTF-8"?>
<result>
<value/>
<ref>2</ref>
</result>
<result>
<value/>
<ref>3</ref>
</result>
And the problem is that is empty. What I wanna get is:
<?xml version="1.0" encoding="UTF-8"?>
<result>
<value>B</value>
<ref>2</ref>
</result>
<result>
<value>C</value>
<ref>3</ref>
</result>
I think the problem is the XPath /body/list/toot[#id=value/#ref]/value specifically the condition [#id=value/#ref]. Is not correct it? How to use a value of other element witch is reference by the current one?
Yes the problem is in XPath where the context is changing so you are actually looking for toot element which has #id attribute and value child with #ref attribute (which is actually child of foo) and these two are equal.
You can employ current() function to make it working
<xsl:value-of select="/body/list/toot[#id=current()/value/#ref]/value"/>
Or you can store value of #ref into a variable and use this variable in predicate
<xsl:variable name="tmpRef" select="value/#ref" />
<xsl:value-of select="/body/list/toot[#id=$tmpRef]/value"/>

How to merge two xml file using xslt1.0?

File1.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<myid>1</myid>
</data>
<data>
<title>Title2</title>
<description>Description2</description>
<myid>2</myid>
</data>
</catalog>
File2.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<author>Author1</author>
<date>12/34/5678</date>
<myid>1</myid>
</data>
<data>
<author>Author2</author>
<date>87/65/4321</date>
<myid>2</myid>
</data>
</catalog>
need output like below using xslt1.0
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<myid>1</myid>
<author>Author1</author>
<date>12/34/5678</date>
</data>
<data>
<title>Title2</title>
<description>Description2</description>
<myid>2</myid>
<author>Author2</author>
<date>87/65/4321</date>
</data>
</catalog>
You need to use the document() function, like so:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/">
<catalog>
<!-- Apply to all data elements in file 1 -->
<xsl:apply-templates select="document('file1.xml')/catalog/data" />
</catalog>
</xsl:template>
<xsl:template match="data">
<data>
<!--Use myid as a lookup-->
<xsl:variable name="myId" select="myid/text()" />
<!--copy all data child nodes from file1-->
<xsl:copy-of select="#* | node()"/>
<!--copy all data child nodes from file2, excluding myid as we already have it-->
<xsl:copy-of select="document('file2.xml')/catalog/data[myid=$myId]/*[not(local-name()='myid')]"/>
</data>
</xsl:template>
</xsl:stylesheet>