문제

I want to do two tasks on the following xml using xslt. can you please help, thank you.

  1. where there is string 'null' replace it by empty string
  2. where SSN starts with zeros truncate them

Can someone put me in the right direction please?

Source XML:

<?xml version='1.0'?>
<!-- This file represents a fragment of a book store inventory database -->
<bookstore>
    <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
            <SSN>0001111</SSN>
            <address></address>
        </author>
        <price>8.99</price>
    </book>
    <book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
            <SSN>0001112</SSN>
            <address></address>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <first-name>JJ</first-name>
            <last-name>MM</last-name>
            <SSN>0001113</SSN>
            <address>null</address>
        </author>
        <price>5.99</price>
    </book>
</bookstore>    

Resulting XML sample

<bookstore>
    <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
            <SSN>0001112</SSN>
            <address></address>
        </author>
        <price>8.99</price>
    </book>

    ...

</bookstore>
도움이 되었습니까?

해결책

You can accomplish what you want with two specialized templates in an identity transform.

  1. A template for SSN that uses either xsl:number or the number() function to remove the leading zeros
  2. A template that matches any element who's computed value is "null" and copies the element without any of it's content.

Applied in the following stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <!--identity template, which will copy all content by default-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!--For all SSN elements,
        copy the matched element and use xsl:number to
        remove any leading zeros from the value -->
    <xsl:template match="SSN">
        <xsl:copy>
            <xsl:number value="."/>
        </xsl:copy>
    </xsl:template>

    <!--for any element who's computed value is "null",
        copy the element and do not copy it's value(removing "null")-->
    <xsl:template match="*[.='null']">
        <xsl:copy/>
    </xsl:template>

</xsl:stylesheet>

A shorter version that matches on the text() nodes instead of their elements:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <!--identity template, which will copy all content by default-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!--For all text() nodes of SSN elements,
        Use xsl:number to remove any leading zeros from the value -->
    <xsl:template match="SSN/text()">
        <xsl:number value="."/>
    </xsl:template>

    <!--for any text() node who's value is "null", suppress it from the output-->
    <xsl:template match="*/text()[.='null']"/>

</xsl:stylesheet>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top