Re: [xsl] Seek an elegant way to remove a sub-tree from an element

Subject: Re: [xsl] Seek an elegant way to remove a sub-tree from an element
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sat, 22 Oct 2011 15:52:51 -0400
At 2011-10-22 19:19 +0000, Costello, Roger L. wrote:
Hi Folks,

This simpleType element contains within it another simpleType element:

<xs:simpleType name="BostonAreaElevation">
        <xs:restriction>
                <xs:simpleType>
                        <xs:restriction base="xs:int">
                                <xs:minInclusive value="-1290" />
                                <xs:maxInclusive value="29035" />
                        </xs:restriction>
                </xs:simpleType>
                <xs:minInclusive value="0" />
                <xs:maxInclusive value="120" />
        </xs:restriction>
</xs:simpleType>

I want to remove the inner simpleType, thus producing:

<xs:simpleType name="BostonAreaElevation">
        <xs:restriction>
                <xs:minInclusive value="0" />
                <xs:maxInclusive value="120" />
        </xs:restriction>
</xs:simpleType>

I seek an elegant way to accomplish this.

The following is one way to accomplish it. Is there a more elegant way to accomplish it?

You don't show us what the variable "simpleType" is.


<xsl:variable name="outer-simpleType">
<xsl:element name="simpleType" namespace="{namespace-uri($simpleType)}">
<xsl:copy-of select="$simpleType/namespace::*" />
<xsl:for-each select="$simpleType/@*">
<xsl:attribute name="{name(.)}"><xsl:value-of select="." /></xsl:attribute>
</xsl:for-each>
<xsl:element name="restriction" namespace="{namespace-uri(simpleType/xs:restriction)}">
<xsl:copy-of select="$simpleType/xs:restriction/namespace::*" />
<xsl:for-each select="$simpleType/xs:restriction/@*">
<xsl:attribute name="{name(.)}"><xsl:value-of select="." /></xsl:attribute>
</xsl:for-each>
<xsl:sequence select="$simpleType/xs:restriction/xs:*[not(self::xs:simpleType)]" />
</xsl:element>
</xsl:element>
</xsl:variable>

Something along the lines of this untested fragment?


 <xsl:variable name="outer-simpleType">
   <xsl:for-each select="$simpleType">
     <xsl:copy>
       <xsl:copy-of select="@*"/>
       <xsl:for-each select="restriction">
          <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:copy-of select="* except xs:simpleType"/>

... if you have to use XSLT 1.0 the last line would be:

<xsl:copy-of select="*[not(self::xs:simpleType)]"/>

Or, better yet, use an identity transform?

<xsl:variable name="outer-simpleType">
<xsl:apply-templates select="$simpleType" mode="copyAllButNestedSimpleType"/>
</xsl:variable>


 <xsl:template mode="copyAllButNestedSimpleType"
               match="xs:simpleType//xs:simpleType"/>
 <xsl:template mode="copyAllButNestedSimpleType" match="*">
  ... identity ...
 </xsl:template>

Even better, not create it in the first place?

I hope these help.

. . . . . . . . . . . . Ken


-- Contact us for world-wide XML consulting and instructor-led training Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Google+ profile: https://plus.google.com/116832879756988317389/about Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread