Sample XML:
<MAIN>
<A>
<first_name>Franklin</first_name>
<first_name_Previous></first_name_Previous>
<formal_name>Franklin Alagala </formal_name>
<gender>M</gender>
<is_overridden>false</is_overridden>
</A>
<B>
<first_name>Franklin</first_name>
<formal_name>Franklin Alagala </formal_name>
<gender>M</gender>
<gender_Previous></gender_Previous>
<is_overridden>false</is_overridden>
</B>
</MAIN>
Expected Output:
<MAIN>
<A>
<first_name>Franklin</first_name>
<first_name_Previous>ABCD</first_name_Previous>
<formal_name>Franklin Alagala </formal_name>
<gender>M</gender>
<is_overridden>false</is_overridden>
</A>
<B>
<first_name>Franklin</first_name>
<formal_name>Franklin Alagala </formal_name>
<gender>M</gender>
<gender_Previous>ABCD</gender_Previous>
<is_overridden>false</is_overridden>
</B>
</MAIN>
Want to replace the node which contains name as previous and the node is empty. However if the node contains name as previous and value is present it should leave the name as it is.
Let me put your description a little other way, which better leads to the expected solution.
You look at each child element of MAIN
( A
, B
and possibly C
, D
and so on), let's call it buckets .
Each bucket you want to process the following way:
Then we can write the above rules in XSL as follows:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="MAIN/*/*">
<xsl:copy>
<xsl:call-template name="proc_node"/>
</xsl:copy>
</xsl:template>
<xsl:template name="proc_node">
<xsl:variable name="thisName" select="name()"/>
<xsl:variable name="cnt" select="string-length(.)"/>
<xsl:if test="$cnt > 0">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test="$cnt = 0">
<xsl:variable name="prevBucket" select="../preceding-sibling::*[1]"/>
<xsl:variable name="prevElem" select="$prevBucket/*[name()=$thisName]"/>
<xsl:variable name="cnt" select="string-length($prevElem)"/>
<xsl:if test="$cnt > 0">
<xsl:value-of select="$prevElem"/>
</xsl:if>
<xsl:if test="$cnt = 0">ABCD</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>
I don't know how to locate the node having previous in the name.
Try:
*[contains(name(), 'Previous')]
If you want to further restrict this to empty elements, you can use:
*[contains(name(), 'Previous') and not(node())]
Note that XML is case-sensitive; "previous" is not the same thing as "Previous".
I have written the code which is working fine:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">
<xsl:output indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:if test="contains(name(), '_previous')">
<xsl:if test="not(string(.))">PREVIOUS</xsl:if>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.