Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / XML / September 2006

Tip: Looking for answers? Try searching our database.

Urgent XSL question, please help, thanks

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
davidw - 26 Sep 2006 21:08 GMT
I have xml tree like

<root>
<field name="l1">
<field name="l11">
 <field name="l111"/>
 <field name="l112"/>
</field>
<field name="l2" stop="true">
 <field name="l21">
  <field name="l211"/>
  <field name="l212"/>
 </field>
 <field name="l22"/>
</field>
<field name="l3"/>
</root>

The tree could have many levels, I need a for-each to collect all node name
under current context, the key is the current context could be on any node,
for example, it could be the "l1", it could be "l2" or node under "l2". I
tried to use code like

<xsl:for-each select=".//field[not(@stop)]/field">
<xsl:value-of select="@name"/>,
</xsl:for-each>

It do the recursive loop, the problem is if the current context is "l2", it
will not work. The idea is it check all childnodes without "stop", not the
start node (the current context). I have no way to know if the node is top
node in // , and I don't know how to get current level ( I remember there
isn't such function).

Any idea?

Thanks!
Peter Flynn - 26 Sep 2006 22:20 GMT
> I have xml tree like
>
[quoted text clipped - 13 lines]
> <field name="l3"/>
> </root>

Your XML is not well-formed: it's missing a </field> end-tag before the
</root> end-tag.

> The tree could have many levels, I need a for-each to collect all node name
> under current context, the key is the current context could be on any node,
> for example, it could be the "l1", it could be "l2" or node under "l2". I
> tried to use code like

I'm not clear what you want to do, create a node-set of all the @name
attributes of field elements which are descendants of the context
element, or list the @name values. Here is an XSLT script which lists
the values. No need for for-each: use templates.

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

  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="field">
    <xsl:value-of select="@name"/>
    <xsl:text>: </xsl:text>
    <xsl:apply-templates select="descendant::field" mode="sub"/>
    <xsl:text>&#xA;</xsl:text>
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="field" mode="sub">
    <xsl:value-of select="@name"/>
    <xsl:text> </xsl:text>
  </xsl:template>

</xsl:stylesheet>

It's also not clear what you want to do with the element with a stop
value: cease processing, or simply exclude it (and its descendants)
from the recursion?

///Peter
Signature

XML FAQ: http://xml.silmaril.ie/

///Peter

davidw - 27 Sep 2006 05:40 GMT
Hi,

 Thanks.

 The XML has a type error. It just a fake data to demo what I want.

 It seems I didn't express clearly. What I need is from any node, I can get
all names in its subtree, but exclude those with a stop attribute. check
this xml

<field name="n0">
<field name="n1">
 <field name="n11">
  <field name="n111"/>
  <field name="n112"/>
 </field>
 </field>
 <field name="n2" stop="true">
  <field name="n21">
   <field name="n211"/>
   <field name="n212"/>
  </field>
  <field name="n22"/>
 </field>
<field name="n3"/>
</field>

For example, it the current node is n0, I will get
n11,n111,n112,n2,n3    -- it will not go into n2 since it has a stop
if the current node is n2, I should get n21,n211,n212,n22   -- it should not
affected by the stop, since it only filter childnodes with stop attribute.

I get used to use for-each. Is there a way to do that with for-each?

Thanks!

> > I have xml tree like
> >
[quoted text clipped - 54 lines]
>
> ///Peter
davidw - 27 Sep 2006 05:40 GMT
Hi,

 Thanks.

 The XML has a type error. It just a fake data to demo what I want.

 It seems I didn't express clearly. What I need is from any node, I can get
all names in its subtree, but exclude those with a stop attribute. check
this xml

<field name="n0">
<field name="n1">
 <field name="n11">
  <field name="n111"/>
  <field name="n112"/>
 </field>
 </field>
 <field name="n2" stop="true">
  <field name="n21">
   <field name="n211"/>
   <field name="n212"/>
  </field>
  <field name="n22"/>
 </field>
<field name="n3"/>
</field>

For example, it the current node is n0, I will get
n11,n111,n112,n2,n3    -- it will not go into n2 since it has a stop
if the current node is n2, I should get n21,n211,n212,n22   -- it should not
affected by the stop, since it only filter childnodes with stop attribute.

I get used to use for-each. Is there a way to do that with for-each?

Thanks!

> > I have xml tree like
> >
[quoted text clipped - 54 lines]
>
> ///Peter
Peter Flynn - 27 Sep 2006 22:08 GMT
>   The XML has a type error. It just a fake data to demo what I want.

The problem is that if you want someone to work on what you provide,
it's a courtesy to provide data that can be used.

> It seems I didn't express clearly. What I need is from any node, I can get
> all names in its subtree, but exclude those with a stop attribute. check
[quoted text clipped - 21 lines]
> if the current node is n2, I should get n21,n211,n212,n22   -- it should not
> affected by the stop, since it only filter childnodes with stop attribute.

OK, now I get it.

> I get used to use for-each.

Don't. The for-each is normally kept for processing nodes out of
document sequence, or for processing nodes sorted into a different
order.

> Is there a way to do that with for-each?

Possibly, but that's procedural thinking. XSLT isn't like that.

This seems to do the trick:

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

  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="field">
    <xsl:value-of select="@name"/>
    <xsl:text>: </xsl:text>
    <xsl:apply-templates select="child::field[not(@stop='true')]"
mode="sub"/>
    <xsl:text>&#xA;</xsl:text>
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="field" mode="sub">
    <xsl:value-of select="@name"/>
    <xsl:text> </xsl:text>
    <xsl:apply-templates select="child::field[not(@stop='true')]"
mode="sub"/>
  </xsl:template>

</xsl:stylesheet>

///Peter

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.