tags:

views:

25

answers:

2

I want to skip the child element from following xml

<person id="101">
    <name>XYZ</name>
    <last-name>XXX</last-name>
</person>
<person id="101">
    <name>YYY</name>
    <last-name>BBB</last-name>
</person>

Assuming I want to skip last-name and here is my code

<xsl:template match="/">
   <xsl:apply-templates select="//person [not(last-name)]" />
</xsl:template>
<xsl:template match="person">
<xsl:copy-of select="." />
<xsl:text>&#xa;</xsl:text>
</xsl:template>

The above code skips the all person element who has last-name element.

Can any any one help me with this code?

Thanks

+1  A: 

By "skip last name" I take it you want your output to look like this:

<person id="101">
  <name>XYZ</name>
</person>
<person id="101">
  <name>YYY</name>
</person>

In which case your approach will have to include all person elements. A standard way of copying everything but a particular element works like this:

<xsl:template match="/">
  <xsl:apply-templates select="//person"/>
</xsl:template>
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="last-name">
  <!-- Do nothing, you don't want to copy this. -->
</xsl:template>

I think you are misunderstanding how XPath expressions work. Your expression //person [not(last-name)] is selecting all person elements matching the condition not(last-name), which means it matches any person elements which do not have child last-name elements. It's behaving exactly as it should.

Welbog
@Welbog: Please do not recommend expressions that begin with `//` because they are very inefficient.
Alejandro
+1  A: 

With proper input:

<root>
    <person id="101">
        <name>XYZ</name>
        <last-name>XXX</last-name>
    </person>
    <person id="101">
        <name>YYY</name>
        <last-name>BBB</last-name>
    </person>
</root>

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
<xsl:template match="@*|node()">
<xsl:copy>
   <xsl:apply-templates select="@*|node()" />
   </xsl:copy>
</xsl:template>
<xsl:template match="last-name"/>
</xsl:stylesheet>

Produce what I think is the desired result:

<root>
    <person id="101">
        <name>XYZ</name>
    </person>
    <person id="101">
        <name>YYY</name>
    </person>
</root>

Note: Identity Transform. Empty template to strip nodes.

Alejandro
Thank you. Worked perfect!
jason
@jason4: You are wellcome! Also, in order to help others, please, edit your question and make clear that you want to strip `last-name` element.
Alejandro