BizTalk Utilities Xselerator XSLT IDE


Forum main page

Most active member

Login page
Register
Log out

Search page

View our event calendar
Add general event such as an upcoming software release or conference
View all birthdays

Public image gallery
Upload your images in your profile

Profile editing page
Subscription list page
Address book page

Member list page
View the most active member
User groups listing

Private message page

TopXML Discussion Forum TopXML Discussion Forum

Forums  Register  Login  My Profile  Inbox  Address Book  My Subscription  My Forums 

Photo Gallery  Member List  Search  Calendars  FAQ  Ticket List  Log Out

Filter with xsl

 
View related threads: (in this forum | in all forums)

Logged in as: Guest
Users viewing this topic: none
  Printable Version
All Forums >> [Ask XML questions here] >> XSLTalk (Programming) >> Filter with xsl Page: [1]
Login
Message << Older Topic   Newer Topic >>
Filter with xsl - 28 March 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
Hi,

I need some help with removing the attribute "pagecount" and leave 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="220221" />
<
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
Post #: 1
RE: Filter with xsl - 29 March 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
please, I really need some help with this

I know how to remove the whole Page tag but not how to only remove an attribute.

(in reply to crazy_horse)
Post #: 2
RE: Filter with xsl - 1 April 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
Copy template
<xsl:template match="*">
<xsl:copy-of select="@*[name() != 'pagecount']"/>
<xsl:apply-templates/>
</xsl:template>

(in reply to crazy_horse)
Post #: 3
RE: Filter with xsl - 3 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
Thank you for your answer jkmyoung!

But I can't get this to work. I'm trying to change an existing xsl that looks like this in the end

<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>

If I don't add self::Contents to the blue line above, everything (including pagecount) in Contents are copied. If I add self::Contents to the blue line I miss a lot of other tags. I haven't worked with xsl before so all help is appreciated  :)

(in reply to jkmyoung)
Post #: 4
RE: Filter with xsl - 4 April 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
<xsl:template match="*" mode="copy">
<xsl:copy>
  <xsl:copy-of select="@*[name() != 'pagecount']"/>
  <xsl:apply-templates mode="copy"/>
</xsl:copy>
</xsl:template>

replace the line with:

<xsl:apply-templates select="*[not(self::ArticleIdentifier|self::ContentFiles|self::FirstValidDateTime|self::LastValidDateTime|self::PostProcessedBy)]" mode="copy"/>

< Message edited by jkmyoung -- 10 April 2008 >

(in reply to crazy_horse)
Post #: 5
RE: Filter with xsl - 4 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
Thank you, jkmyoung. I will try that

(in reply to jkmyoung)
Post #: 6
RE: Filter with xsl - 7 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
hmm... I get this error message when I try your example:

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.InvalidOperationException:
There was an error generating the XML document. ---> System.Xml.Xsl.XslTransformException: Attribute and namespace nodes
cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added.
  at System.Xml.Xsl.Runtime.XmlQueryOutput.ThrowInvalidStateError(XPathNodeType constructorType)
  at System.Xml.Xsl.Runtime.XmlQueryOutput.ConstructInEnumAttrs(XPathNodeType rootType)
  at System.Xml.Xsl.Runtime.XmlQueryOutput.WriteStartAttribute(String prefix, String localName, String ns)
  at System.Xml.Xsl.Runtime.XmlQueryOutput.StartCopy(XPathNavigator navigator, Boolean callChk)
  at System.Xml.Xsl.Runtime.XmlQueryOutput.CopyNode(XPathNavigator navigator)
  at System.Xml.Xsl.Runtime.XmlQueryOutput.WriteItem(XPathItem item)
  at <xsl:template match="*" mode="copy">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
  at <xsl:template match="*" mode="copy">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
  at <xsl:template match="*" mode="copy">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
  at <xsl:template match="OriginalMetaXml/PressItem">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
  at <xsl:template match="MetaXml">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
  at <xsl:template match="MetaXmls">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
  at <xsl:template match="FindMediaItemsResponse">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
  at <xsl:apply-templates>(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator )
  at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
  at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
  at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
  at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
  at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
  at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XsltArgumentList arguments, XmlWriter results)
  at SecureWS.XmlResponseNode.WriteTo(XmlWriter writer)
  at System.Xml.Serialization.XmlSerializationWriter.WriteElement(XmlNode node, String name, String ns, Boolean isNullable, Boolean any)
  at System.Xml.Serialization.XmlSerializationWriter.WriteElementLiteral(XmlNode node, String name, String ns, Boolean isNullable, Boolean any)
  at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write4_FindPressItemsResponse(Object[] p)
  at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer1.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
  at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
  --- End of inner exception stack trace ---
  at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
  at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle)
  at System.Web.Services.Protocols.SoapServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
  at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
  at System.Web.Services.Protocols.WebServiceHandler.Invoke()
  --- End of inner exception stack trace ---

seems like it don't like mode="copy"

(in reply to jkmyoung)
Post #: 7
RE: Filter with xsl - 10 April 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
My mistake, missed the <xsl:copy> nodes.
See above code again.

(in reply to crazy_horse)
Post #: 8
RE: Filter with xsl - 11 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
jkmyoung, you're the man.   Thank you VERY much for your help

(in reply to jkmyoung)
Post #: 9
RE: Filter with xsl - 21 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
ok, next stupid question.

I want to filter two values in the same tag, how do I do that? I was thinking that it could be done like the example below but obviously that is wrong.

<
xsl:template match="*" mode="copy">
<
xsl:copy>
<
xsl:copy-of select="@*[name() != 'pagecount' | name() != 'pagespread']"/>
<
xsl:apply-templates mode="copy"/>
</
xsl:copy>
</
xsl:template>

(in reply to crazy_horse)
Post #: 10
RE: Filter with xsl - 21 April 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
use 'and' instead of 'or'.

(in reply to crazy_horse)
Post #: 11
RE: Filter with xsl - 22 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
great, thanks again!

(in reply to jkmyoung)
Post #: 12
RE: Filter with xsl - 25 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
Is it possible to manipulate values in attributes? Today it looks like the first example but I only want the first values like it is on the second example ie ,23, 28 has been removed from top and ", 967, 872" has been removed from Area. The number of values differes from file to file.
 
<PagePosition unit="mm" top="24, 23, 28" left="98, 0" />

  <Area unit="cm">665, 967, 872</Area> I  <PagePosition unit="mm" top="24" left="98, 0" />

  <Area unit="cm">665</Area>

(in reply to crazy_horse)
Post #: 13
RE: Filter with xsl - 25 April 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
when context is on attribute
<xsl:choose>
<xsl:when test="contains(.,',')"><xsl:value-of select="substring-before(.,',')"/></xsl:when>
<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
</xsl:choose>

I seriously suggest asking each new question in a new thread for faster response. Most normal people won't bother reading a 13 reply post.

(in reply to crazy_horse)
Post #: 14
RE: Filter with xsl - 28 April 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
Ok, I will do that next time. Since I already have started this issue in this thread I will post my reply here.

I have been struggling with the xsl:choose statement for some time now and I can't manage to get it to work with the other piece of code you have helped me with. The mode="copy" just copies everything in the PagePosition tag. How do I force it to use the xsl:choose check instead? The xsl looks like this:

<
xsl:template match="OriginalMetaXml/PressItem">
<
xsl:apply-templates select="*[not(self::ArticleIdentifier|self::ContentFiles|self::FirstValidDateTime|self::LastValidDateTime|self::PostProcessedBy)]" mode="copy"/>
</
xsl:template>
 

<
xsl:template match="*" mode="copy">
<
xsl:copy>
<
xsl:copy-of select="@*[name() != 'pagecount' and name() != 'pagespread']"/>
<
xsl:apply-templates mode="copy"/>
</
xsl:copy>
</
xsl:template>


<Contents>
<
Content>
<
Section seqno="01" />
<
Page seqno="220221" pagecount="5,6" />
<
PageSize unit="" width="" height="14.36" />
<
PagePosition unit="" top="10,20" left="30,40" />
<
Area unit="cm2">360,370</Area>
<
Headline>Something</Headline>
<
Byline />
<
Introduction />
<
Body />
<
Pictures>
<
captions />
</
Pictures>
</
Content>
</
Contents>

(in reply to jkmyoung)
Post #: 15
RE: Filter with xsl - 30 April 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
Create a different template for PagePosition with mode copy
<xsl:template match="PagePosition" mode="copy">
... your code here.

(in reply to crazy_horse)
Post #: 16
RE: Filter with xsl - 2 May 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
Thank you for your patience...

I have tried that but it removes the whole PagePosition tag when I do that.

<
xsl:template match="OriginalMetaXml/PressItem">
<
xsl:apply-templates select="*[not(self::ArticleIdentifier|self::ContentFiles|self::FirstValidDateTime|self::LastValidDateTime|self::PostProcessedBy)]" mode="copy"/>
</
xsl:template>
 
<
xsl:template match="*" mode="copy">
<
xsl:copy>
<
xsl:copy-of select="@*[name() != 'pagecount' and name() != 'pagespread']"/>
<
xsl:apply-templates mode="copy"/>
</
xsl:copy>
</
xsl:template>
 
<
xsl:template match="PagePosition" mode="copy">
<xsl:choose>
<
xsl:when test="contains(.,',')">
<
xsl:value-of select="substring-before(.,',')"/>
</
xsl:when>
<
xsl:otherwise>
<
xsl:value-of select="."/>
</
xsl:otherwise>
</
xsl:choose>
</xsl:template>

If I do it like this then I got a empt PagePosition tag

<
xsl:template match="OriginalMetaXml/PressItem">
<
xsl:apply-templates select="*[not(self::ArticleIdentifier|self::ContentFiles|self::FirstValidDateTime|self::LastValidDateTime|self::PostProcessedBy)]" mode="copy"/>
</
xsl:template>
 
<
xsl:template match="*" mode="copy">
<
xsl:copy>
<
xsl:copy-of select="@*[name() != 'pagecount' and name() != 'pagespread']"/>
<
xsl:apply-templates mode="copy"/>
</
xsl:copy>
</
xsl:template>
 
<
xsl:template match="PagePosition" mode="copy">
<
PagePosition>
<
xsl:choose>
<
xsl:when test="contains(.,',')">
<
xsl:value-of select="substring-before(.,',')"/>
</
xsl:when>
<
xsl:otherwise>
<
xsl:value-of select="."/>
</
xsl:otherwise>
</
xsl:choose>
</
PagePosition>
</
xsl:template>

(in reply to jkmyoung)
Post #: 17
RE: Filter with xsl - 2 May 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
Change other copy template to:
<xsl:template match="*|@*" mode="copy">
<
xsl:copy>
<
xsl:copy-of select="@*[name() != 'pagecount' and name() != 'pagespread']"/>
<
xsl:apply-templates mode="copy"/>
</
xsl:copy>
</
xsl:template>

pageposition template :
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="copy"/>
</xsl:copy>
...

<xsl:template match="@top">
<xsl:choose>
...
</xsl:choose>
</xsl:template>

(in reply to crazy_horse)
Post #: 18
RE: Filter with xsl - 5 May 2008   
crazy_horse

 

Posts: 13
Score: 0
Joined: 28 March 2008
Status: offline
Thank you! The first template works fine but the values in @top isn't filtered.

<xsl:template match="*|@*" mode="copy">
<
xsl:copy>
<
xsl:copy-of select="@*[name() != 'pagecount' and name() != 'pagespread']"/>
<
xsl:apply-templates mode="copy"/>
</
xsl:copy>
</
xsl:template>
 
<
xsl:template match="PagePosition" mode="copy">
<
xsl:copy>
<
xsl:apply-templates select="node()|@*" mode="copy"/>
<
xsl:apply-templates select="@top"/>
</
xsl:copy>
</
xsl:template>
 
<
xsl:template match="@top">
<
xsl:choose>
<
xsl:when test="contains(.,',')">
<
xsl:value-of select="substring-before(.,',')"/>
</
xsl:when>
<
xsl:otherwise>
<
xsl:value-of select="."/>
</
xsl:otherwise>
</
xsl:choose>
</
xsl:template>

(in reply to jkmyoung)
Post #: 19
RE: Filter with xsl - 5 May 2008   
jkmyoung

 

Posts: 259
Score: 6
Joined: 14 September 2004
Status: offline
Is it always guaranteed that you'll have the same number of area values as top values?
otherwise, you could simply do the same with both

<xsl:template match="@top|Area">
<xsl:copy>
  <xsl:copy-of select="@*"/>
<xsl:choose>
<
xsl:when test="contains(.,',')">
<
xsl:value-of select="substring-before(.,',')"/>
</
xsl:when>
<
xsl:otherwise>
<
xsl:value-of select="."/>
</
xsl:otherwise>
</
xsl:choose>
</xsl:copy>
</
xsl:template>

(in reply to crazy_horse)