i have two xml files:
<m2>
<header>
<to>ggg</to>
<from>aaa</from>
<id>11</id>
<name>gd</name>
<mtype>me</mtype>
</header>
<body>some text</body>
</m2>
2.
<m2>
<header>
<desc>
<to>ggg</to>
<from>aaa</from>
</desc>
<id>11</id>
<name>gd</name>
<mtype>nothing</mtype>
</header>
<body>some text</body>
</m2>
what is the xslt file that convert from the first xml to the second xml?
the xslt need to transform the value of the mtype from "me" to "some text"
and insert the "to" and "from" elements into the "desc" element.
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="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="to">
<desc>
<xsl:copy-of select=".|../from"/>
</desc>
</xsl:template>
<xsl:template match="mtype/text()">nothing</xsl:template>
<xsl:template match="from"/>
</xsl:stylesheet>
when applied o the provided XML document, restored from the picture ( Never do this again!):
<m2>
<header>
<to>ggg</to>
<from>aaa</from>
<id>11</id>
<name>gd</name>
<mtype>me</mtype>
</header>
<body>some text</body>
</m2>
produces the wanted result:
<m2>
<header>
<desc>
<to>ggg</to>
<from>aaa</from>
</desc>
<id>11</id>
<name>gd</name>
<mtype>nothing</mtype>
</header>
<body>some text</body>
</m2>
Explanation: Simple application of the identity rule design pattern. Using and overriding the identity template is the most fundamental and powerful XSLT design pattern.
See examples and explanations at: http://dpawson.co.uk/xsl/sect2/identity.html
There's a lot of tutorials for this; just do a web search on "XSLT Tutorial". Here's one of the sites:
http://www.w3schools.com/xsl/
Related
I need to do the following transformation in order to get a message pass through a integration broker which does not understand xsi:nil=“true”. I know that for strings having some thing like <abc></abc> is not same as <abc xsi:nil=“true”/> but I have no option.
My input XML:
<PART>
<LENGTH_UOM xsi:nil="1"/>
<WIDTH xsi:nil="1"/>
</PART>
Expected outcome:
<PART>
<LENGTH_UOM><LENGTH_UOM>
<WIDTH></WIDTH>
</PART>
Please let me know your suggestions.
To remove all xsi:nil attributes combine the identity template with an empty template matching xsi:nil.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://xsi.com">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|#*"> <!-- identity template -->
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<xsl:template match="#xsi:nil" /> <!-- empty template -->
</xsl:stylesheet>
If you only want to remove those whose value is true use the following empty template instead.
<xsl:template match="#xsi:nil[.='1' or .='true']" />
Concerning the opening and closing tag topic I suggest reading this SO question in which Martin Honnen states that (in the comments of the answer):
I am afraid whether an empty element is marked up as or or is not something that matters with XML and is usually not something you can control with XSLT processors.
Im a bit new to splitting XMLs, Can you help me create multiple XMLs from one input? do I need to use splitters? XSLT? also, can i plud in the message id in the xml as well?
Input
<?xml version="1.0"?>
<StockMovementDataRequest xmlns:p1="urn:ams.com.au:dynamo:3pl:am:SAP_AM_I_005:StockMovement" xmlns:a="http://www.edi.com.au/EnterpriseService">
<Header>
<From>Warehouse</From>
<To>Location</To>
<Unique_ID>idm1468201212</Unique_ID>
<DateTimeStamp>2016-04-13T11:55:30.263+10:00</DateTimeStamp>
</Header>
<StockMovementData>
<Serialised_Material>YES</Serialised_Material>
<DateTime>2016-04-13T11:55:30.263+10:00</DateTime>
<From_Location>30-80</From_Location>
<To_Location>client</To_Location>
<Material>7CAGL3G00</Material>
<Serial>700030011</Serial>
<Quantity>100</Quantity>
</StockMovementData>
<StockMovementData>
<Serialised_Material>YES</Serialised_Material>
<DateTime>2016-04-13T11:55:30.263+10:00</DateTime>
<From_Location>30-80</From_Location>
<To_Location>client</To_Location>
<Material>7CAGL3G00</Material>
<Serial>700029911</Serial>
<Quantity>100</Quantity>
</StockMovementData>
</StockMovementDataRequest>
output
<?xml version="1.0"?>
<StockMovementDataRequest xmlns:p1="urn:ams.com.au:dynamo:3pl:am:SAP_AM_I_005:StockMovement"
xmlns:a="http://www.edi.com.au/EnterpriseService/">
<Header>
<From>warehouse</From>
<To>client</To>
<Unique_ID>idm1467386212</Unique_ID>
<DateTimeStamp>2016-04-13T11:55:30.263+10:00</DateTimeStamp>
</Header>
<StockMovementData>
<Serialised_Material>YES</Serialised_Material>
<DateTime>2016-04-13T11:55:30.263+10:00</DateTime>
<From_Location>30-80</From_Location>
<To_Location>client</To_Location>
<Material>7CAGL3G00</Material>
<Serial>700030011</Serial>
<Quantity>100</Quantity>
</StockMovementData>
</StockMovementDataRequest>
and
<?xml version="1.0"?>
<StockMovementDataRequest xmlns:p1="urn:ams.com.au:dynamo:3pl:am:SAP_AM_I_005:StockMovement"
xmlns:a="http://www.edi.com.au/EnterpriseService/">
<Header>
<From>warehouse</From>
<To>client</To>
<Unique_ID>idm1467386212</Unique_ID>
<DateTimeStamp>2016-04-13T11:55:30.263+10:00</DateTimeStamp>
</Header>
<StockMovementData>
<Serialised_Material>YES</Serialised_Material>
<DateTime>2016-04-13T11:55:30.263+10:00</DateTime>
<From_Location>30-80</From_Location>
<To_Location>client</To_Location>
<Material>7CAGL3G00</Material>
<Serial>700029911</Serial>
<Quantity>100</Quantity>
</StockMovementData>
</StockMovementDataRequest>
Any thoughts?
If your processor supports XSLT-2.0, you can try the code below:
<?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:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:for-each select="StockMovementDataRequest/StockMovementData">
<xsl:result-document href="{concat('output', position(), '.xml')}">
<StockMovementDataRequest xmlns:p1="urn:ams.com.au:dynamo:3pl:am:SAP_AM_I_005:StockMovement" xmlns:a="http://www.edi.com.au/EnterpriseService">
<xsl:apply-templates select="preceding-sibling::Header"/>
<xsl:apply-templates select="."/>
</StockMovementDataRequest>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
it outputs, output1.xml and output2.xml based on your input.
Use Mule Splitter to split xml
<splitter expression="#[xpath3('//StockMovementDataRequest/StockMovementData',payload,'NODESET')]" doc:name="Splitter"/>
<mulexml:dom-to-xml-transformer doc:name="DOM to XML"/>
To aggregate the payload after splitter, use aggregator
<collection-aggregator doc:name="Collection Aggregator"/>
See more documentation here
https://docs.mulesoft.com/mule-user-guide/v/3.7/splitter-flow-control-reference
I have an incoming XML like below: I need to remove the <shoeboxImage> tag from the incoming below XML.
Incoming XML Input:
<attachReceipt>
<baseMessage>
<returnCode>200</returnCode>
</baseMessage>
<payload>
<returnCode>0</returnCode>
<shoeboxItem>
<shoeboxImageCount>2</shoeboxImageCount>
<shoeboxImages>
<shoeboxImage>
<name>receiptImage.jpg</name>
</shoeboxImage>
<shoeboxImage>
<name>receiptImage.jpg</name>
</shoeboxImage>
</shoeboxImages>
</shoeboxItem>
</payload>
</attachReceipt>
Expected Output:
<attachReceipt>
<baseMessage>
<returnCode>200</returnCode>
</baseMessage>
<payload>
<returnCode>0</returnCode>
<shoeboxItem>
<shoeboxImageCount>2</shoeboxImageCount>
<shoeboxImages>
<name>receiptImage.jpg</name>
<name>receiptImage.jpg</name>
</shoeboxImages>
</shoeboxItem>
</payload>
</attachReceipt>
Need some xslt code snippet to do this.
I don't have the necessary software installed to actually test this, but this should work:
<xsl:template match="shoeboxImage">
<xsl:apply-templates select="*|text()"/>
</xsl:template>
The idea is that when a shoeboxImage element is encountered, it generates nothing for the element itself, and just continues with its children.
You need to have an identity template and a template that will remove the element shoeboxImage but will retain its descendants.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<!-- identity template -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- template override for the element shoeboxImage -->
<xsl:template match="shoeboxImage">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
I have a problem with the XML Web response i am getting. The Inner Loop warehouseItems have a node leadTimeCumulative and leadTimeDays coming on the first and Second Position for the FIrst time, for the Rest its coming last. I need to keep these node always in the Last position in side the Loop.
Example
<Envelope>
<Body>
<searchItemResponse>
<status>
<statusCode>Success</statusCode>
</status>
<itemList>
<itemWithWarehouses>
<item>
<originOfData>SME</originOfData>
<itemNumbers>
<shortNumber>115632</shortNumber>
<tssArticleNumber>PT0401450-T46N</tssArticleNumber>
</item>
<warehouseItems>
<leadTimeCumulative>14</leadTimeCumulative>
<leadTimeDays>14</leadTimeDays>
<warehouse>
<code>GA01</code>
</warehouse>-
<stockItem>-
<quantities>
<quantityAvailable>0</quantityAvailable>
<quantityOnHand>0</quantityOnHand>
</quantities>
</stockItem>-
<stockClass>
<group>MTO</group>
</stockClass>
</warehouseItems>-
<warehouseItems>-
<warehouse>
<code>GL01</code>
</warehouse>-
<stockItem>-
<quantities>
<quantityAvailable>0</quantityAvailable>
<quantityOnHand>0</quantityOnHand>
</quantities>
</stockItem>-
<stockClass>
<group>MTO</group>
</stockClass>
<leadTimeCumulative>14</leadTimeCumulative>
<leadTimeDays>14</leadTimeDays>
</warehouseItems>-
<warehouseItems>-
<warehouse>
<code>GS01</code></warehouse>-
<stockItem>-
<quantities>
<quantityAvailable>0</quantityAvailable>
<quantityOnHand>0</quantityOnHand>
</quantities>
</stockItem>-
<stockClass>
<group>MTO</group>
</stockClass>
<leadTimeCumulative>10</leadTimeCumulative>
<leadTimeDays>10</leadTimeDays>
</warehouseItems>-
</itemWithWarehouses>
</itemList>
</searchItemResponse>
</Body>
</Envelope>
I need any XSLT for changing the position of the node leadTimeCumulative and leadTimeDays to the Last like the rest of the Loop Structure. Please help me.
The above part is solved.
I need an improvement along with this.The tssArticleNumber node need to copy to the respective warehouse items with a different node name like "Item No". Please give me another XSLT for this. Thanks
try the following stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<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="*"/>
<!-- this is called an identity template -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- a template to override warehouseItems -->
<xsl:template match="warehouseItems">
<xsl:copy>
<!-- apply templates except leadTimeCumulative and leadTimeDays -->
<xsl:apply-templates select="node()[not(self::leadTimeCumulative) and not(self::leadTimeDays)]|#*"/>
<Item_No><xsl:value-of select="../item//tssArticleNumber"/></Item_No>
<xsl:apply-templates select="leadTimeCumulative"/>
<xsl:apply-templates select="leadTimeDays"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I have an XML which needs to be reordered and stored in another file. I have done an xslt for that and it works fine.
However if there are comments after the xml ends then these comments are not copied. I need an xslt statement that copies comments which are present
after the root tag ends
Below is a code that explains the following
Original XML
<Company>
<Employee id="100" Name="John" >
<Salary value="15000"/>
<Qualification text="Engineering">
<State name="Kerala" code="02">
<Background text="Indian">
</Employee>
</Company>
<!--This file contains Employee information-->
<!--Please refer the file to get information about an employee-->
XSLT Transformation code
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output indent="yes" omit-xml-declaration="yes" method="xml" />
<xsl:strip-space elements="*"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Employee">
<xsl:copy>
<xsl:apply-templates select="Qualification"/>
<xsl:apply-templates select="Salary" />
<xsl:apply-templates select="Background"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output Obtained
<?xml version="1.0" encoding="utf-8"?>
<Company>
<Employee>
<Qualification text="Engineering" />
<Salary value="15000" />
<Background text="Indian" />
</Employee>
</Company>
Output Required
<?xml version="1.0" encoding="utf-8"?>
<Company>
<Employee>
<Qualification text="Engineering" />
<Salary value="15000" />
<Background text="Indian" />
</Employee>
</Company>
<!--This file contains Employee information-->
<!--Please refer the file to get information about an employee-->
There's nothing wrong with your transformation. I ran the same XSLT over the same XML (corrected to make it well-formed) using xsltproc and I get the correct output including the trailing comments (though they have lost their original indentation and spacing due to the strip-space and the indent="yes" in the stylesheet)
<Company>
<Employee>
<Qualification text="Engineering"/>
<Salary value="15000"/>
<Background text="Indian"/>
</Employee>
</Company><!--This file contains Employee information-->
<!--Please refer the file to get information about an employee-->
It looks like whatever processor or XML parser you're using (presumably a Microsoft one judging by the xmlns:msxsl="urn:schemas-microsoft-com:xslt") is ignoring comments after the end tag of the document element.