Forum Moderators: open
I'm new to XSL and I need some help with removing the attribute "pagecount" and copy the rest of the tags and attributes. How do I do that with XSL?
<Contents>
<Content>
<Section seqno="01" />
<Page seqno="3637" pagecount="1" />
<PageSize unit="" width="" height="14.36" />
<PagePosition unit="" top="" left="" />
<Area unit="cm2">360.63</Area>
<Headline>Something</Headline>
<Byline />
<Introduction />
<Body />
<Pictures>
<captions />
</Pictures>
</Content>
</Contents>
The final result should be like this:
<Contents>
<Content>
<Section seqno="01" />
<Page seqno="3637" />
<PageSize unit="" width="" height="14.36" />
<PagePosition unit="" top="" left="" />
<Area unit="cm2">360.63</Area>
<Headline>Something</Headline>
<Byline />
<Introduction />
<Body />
<Pictures>
<captions />
</Pictures>
</Content>
</Contents>
Thanks
In any case, there are a couple of ways in which you could do it. You can do it exclusively (everything but <pagecount>) or inclusively (specify exactly which elements you'll copy, and format each one).
I need to break out my "XSLT brain." I've been off in PHP and C++ land, which is way different from XSLT.
I know that you will need to have a template that might look like this:
<xsl:template match="Page">
<xsl:element name="Page">
<xsl:if test="@seqno">
<xsl:attribute name="seqno">
<xsl:value-of select="@seqno"/>
</xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:template>
But I don't want to give you more advice than that, simply because it would end up looking like procedural code, which is improper for XSLT.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@* ¦ node()">
<xsl:choose>
<xsl:when test="@pagecount">
<xsl:copy>
<xsl:apply-templates select="@seqno ¦ node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@* ¦ node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
It's an adaptation of the classic "transparent XSLT" which returns the original XML:
<xsl:template match="@* ¦ node()">
<xsl:copy>
<xsl:apply-templates select="@* ¦ node()"/>
</xsl:copy>
</xsl:template>
In my adaptation, I choose if the current node contains the offensive attribute "pagesize". If it does, I apply a template allowing only child elements and approved attributes (in this case, only @seqno). Otherwise I apply a template which allows any child element or attribute.
Beware cutting and pasting the code-- this forum turns pipe "or" characters into "¦"
my wife was out of town when that was filmed. she swore that if I ended up in the hospital with fragments of mint lodged deep in my sinuses, she would be too embarassed to visit me in the ICU
<xsl:template match="MetaXml">
<PressItem>
<xsl:attribute name="id">
<xsl:value-of select="Id" />
</xsl:attribute>
<xsl:if test="OriginalMetaXml/PressItem">
<xsl:attribute name="type">
<xsl:value-of select="OriginalMetaXml/PressItem/@type"/>
</xsl:attribute>
<xsl:copy-of select="Copyright"/>
<xsl:apply-templates select="OriginalMetaXml/PressItem" />
</xsl:if>
</PressItem>
</xsl:template>
<xsl:template match="OriginalMetaXml/PressItem">
<xsl:copy-of select="* [not(self::ArticleIdentifier ¦ self::ContentFiles ¦ self::FirstValidDateTime ¦ self::LastValidDateTime ¦ self::PostProcessedBy)]"/>
</xsl:template>
It's filtering some other tags that I had not included in my exampel. If I don't add self::Contents to line at the end, everything in Contents (including pagecount) are copied. I guess I should use self::Contents and include httpwebwitch solution somehow but I can't figure out how. Anyone?
Say, crazy_horse, what tool are you using to test your XSLT? Do you have a good debugger that lets you edit XSLT and see the transformed output right away?
And... welcome to WebmasterWorld!
This is how it looks right now:
...
<xsl:template match="MetaXml">
<PressItem>
<xsl:attribute name="id">
<xsl:value-of select="Id" />
</xsl:attribute>
<xsl:if test="OriginalMetaXml/PressItem">
<xsl:attribute name="type">
<xsl:value-of select="OriginalMetaXml/PressItem/@type"/>
</xsl:attribute>
<xsl:copy-of select="Copyright"/>
<xsl:apply-templates select="OriginalMetaXml/PressItem" />
</xsl:if>
</PressItem>
</xsl:template>
<xsl:template match="OriginalMetaXml/PressItem">
<xsl:copy-of select="* [not(self::Contents ¦ self::ArticleIdentifier ¦ self::ContentFiles ¦ self::FirstValidDateTime ¦ self::LastValidDateTime ¦ self::PostProcessedBy)]"/>
<xsl:apply-templates select="Contents/Content" />
</xsl:template>
<xsl:template match="Contents/Content">
<xsl:choose>
<xsl:when test="@pagecount">
<xsl:copy>
<xsl:apply-templates select="@seqno ¦ node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@* ¦ node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
I have created the template Contents/Content and call it from the template OriginalMetaXml/PressItem.