XSLT for converting empty body to a SUCCESS message - xslt

I am trying to replace an empty response body, which is getting generated by a successful DELETE operation with a "Success" message via XSLT.
Can anyone help me with the XSLT which can simply print a SUCCESS message, if the response body is empty.
Response Body will be:
<response status="204"> </response>
Expected output:
<response status="204">SUCCESS</response>
Update from comment: If the response is not empty then it should print the same what comes back as a response.
Currently using the below XSLT:
<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="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*) and not(normalize-space())]">
<xsl:element name="{name()}" namespace="{namespace-uri()}"/>
</xsl:template>
</xsl:stylesheet>
But it gives:
<response/>
as output.

Can anyone help me with the XSLT which can simply print a SUCCESS
message, if the response body is empty.
If the response is not empty then it should print the same what comes
back as a response.
Then try:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/response[not(node())]">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:text>SUCCESS</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Related

Filter out specific String using XSLT

Input :
<img xlink:href="figure_one"><?isoimg-id 9324-098_kr1figure1.JPG?></img>
I want to filter out as .jpg part from above input using XSLT. I have no idea to how can I filter out it.
You could simply remove the file extension (regardless of what it is) by using the substring-before() function:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="processing-instruction('isoimg-id')">
<xsl:processing-instruction name="isoimg-id">
<xsl:value-of select="substring-before(., '.')" />
</xsl:processing-instruction>
</xsl:template>
</xsl:stylesheet>

XSLT 1.0 - Move certain elements into a new parent

Thank you for taking the time to look at my question
I have a source xml that looks like so
<root>
<a>asdf</a>
<b>asdfdsaf</b>
<c>adfasd</c>
<d>asddf</d>
<e></e>
<others>
<foo>sdfd</foo>
<bar>hghg</bar>
</others>
</root>
I need to wrap certain elements Eg:a,b,c into a new parent and remove empty elements.
so output like so
<root>
<newparent>
<a>asdf</a>
<b>asdfdsaf</b>
<c>adfasd</c>
</newparent>
<d>asddf</d>
<others>
<foo>sdfd</foo>
<bar>hghg</bar>
</others>
</root>
I managed to remove the empty elements using this XSL -
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(#*) and not(*) and (not(text()) or .=-1)]"/>
<xsl:template match="name">
</xsl:template>
</xsl:stylesheet>
Getting stuck at adding the newparent node. Any pointers/help is much appreciated.
Try it this way:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root">
<xsl:copy>
<newparent>
<xsl:apply-templates select="a|b|c"/>
</newparent>
<xsl:apply-templates select="*[not(self::a or self::b or self::c)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(#* or node())]"/>
</xsl:stylesheet>
<xsl:template match="root">
<xsl:copy>
<newparent>
<xsl:copy-of select="a|b|c"/>
</newparent>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[.= '' or name() ='a' or name()='b' or name()='c']"/>
check it if it is fullfill your requirement.

Removing specific values XML but keeping tag names using XSLT 1.0

I want to remove specific values from my XML but keep the tag names. I've seen examples that do the opposite (remove tags but keep values). Here is my XML:
<Result>
<Max>100</Max>
<Min>10</Min>
<Range>90</Range>
<ResultPoints>
<ResultP1>.</ResultP1>
<ResultP2>.</ResultP2>
<ResultP3>.</ResultP3>
<ResultP4>.</ResultP4>
<ResultP5>.</ResultP5>
</ResultPoints>
</Result>
I want to remove the '.' but keep the tag names so my XML will look like this:
<Result>
<Max>100</Max>
<Min>10</Min>
<Range>90</Range>
<ResultPoints>
<ResultP1/>
<ResultP2/>
<ResultP3/>
<ResultP4/>
<ResultP5/>
</ResultPoints>
</Result>
Here is my XLT. This completely removes the ResultPn tags.
<?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" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[. = '.']">
<xsl:value-of select="''"/>
</xsl:template>
</xsl:stylesheet>
Any Help will be appreciated!
You just need to do an xsl:copy in your template, to copy across the element you have matched. Note you don't really need to output an empty string here either.
Try this XSLT
<xsl:stylesheet version="1.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:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[. = '.']">
<xsl:copy>
<xsl:apply-templates select="#*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Note, I added an xsl:apply-templates to copy across any existing attributes.
Alternatively, you could replace the second template with this one instead (which matches the text node directly, rather than the parent element)
<xsl:template match="text()[. = '.']" />

Add Namespace to anonymous xml

I am trying to add a namespace to an input:
<?xml version="1.0" encoding="utf-8"?>
<VLOG_Export>
<Send_Referenznr_01>3200000042</Send_Referenznr_01>
<Send_Referenznr_06>00000000001000189718</Send_Referenznr_06>
<Send_ID>1Z78A1070461454103</Send_ID>
</VLOG_Export>
Expected Output:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:VLOG_Export xmlns:ns0="http://mycomp.com/VLOG/SD/vlog/export">
<Send_Referenznr_01>sdfsdf</Send_Referenznr_01>
<Send_Referenznr_06>sdfsf</Send_Referenznr_06>
<Send_ID>sdfsdf</Send_ID>
</ns0:VLOG_Export>
Using this xslt :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:element name="{local-name()}" namespace="http://mycomp.com/VLOG/SD/vlog/export">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I get the wrong output.
Any tips welcome.
Thx
This works as expected:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://mycomp.com/VLOG/SD/vlog/export">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/VLOG_Export" priority="1">
<xsl:element name="ns0:{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
See it working: http://xsltransform.net/6rewNyz

Using xslt to change an attribute value using arithmetic operations

I'm trying to bound the value of an xml attribute using xslt/xpath 1.0. In this example, it would be the id attribute on the m_m element.
<blart>
<m_data>
<m_m name="arggg" id="99999999" subs="asas"/>
</m_data>
<m_data>
<m_m name="arggg" id="99" subs="asas"/>
</m_data>
</blart>
If the id is greater then 20000 it gets set to 20000. I have the following xslt. I know it selects the correct node and attribute. It obviously is just outputing 20000. I realize I should have some sort of xpath logic in there but I'm having a hard time developing it. I have some big holes in my knowledge of xpath and xslt. If you can point me in the right direction in helping me understand on what I should be doing I would really appreciate it.
<?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="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match ="m_data/m_m/#id[.> 20000]">20000 </xsl:template>
</xsl:stylesheet>
The expected output would be
<blart>
<m_data>
<m_m name="arggg" id="20000" subs="asas"/>
</m_data>
<m_data>
<m_m name="arggg" id="99" subs="asas"/>
</m_data>
</blart>
You can use the following XSLT that gives flexibility to the attribute you want to change, and keeps everything else as it is:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match ="m_data/m_m/#id[. > 20000]">
<xsl:attribute name="id">20000</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Why don't you try:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match ="m_m/#id[. > 20000]">
<xsl:attribute name="id">20000</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
NOTE: Since I posted this, much better answers were contributed (see here and here). SO won't let me delete this one because it was accepted, but in all fairness and for the sake of quality, I should encourage you to upvote the two aforementioned answers, so that they stand out over this one.
How about this:
<?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="m_m">
<m_m>
<xsl:copy-of select="#*" />
<xsl:if test="#id > 20000">
<xsl:attribute name="id">20000</xsl:attribute>
</xsl:if>
</m_m>
</xsl:template>
<xsl:template match="m_data">
<m_data>
<xsl:apply-templates select="m_m" />
</m_data>
</xsl:template>
<xsl:template match="/blart">
<blart>
<xsl:apply-templates select="m_data" />
</blart>
</xsl:template>
</xsl:stylesheet>