Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > How to display all the ancestors and their attributes of a selected element?

Reply
Thread Tools

How to display all the ancestors and their attributes of a selected element?

 
 
ai2003lian@yahoo.com
Guest
Posts: n/a
 
      02-10-2005
Assuming I have the following two xml file:


source.xml:

<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f2">Value2</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f4">Value4</Field>
<Field fieldName="f5">Value5</Field>
<Field fieldName="f6">Value6</Field>
</Group>
<Group name="G3">
<Field fieldName="f7">Value7</Field>
<Field fieldName="f8">Value8</Field>
<Field fieldName="f9">Value9</Field>
</Group>
</AllFields>

requ*ired.xml:

<RequiredFields>
<FieldName>f1</FieldName>
<FieldName>f3</FieldName>
<FieldName>f6</FieldName>
</RequiredFields>


The requirement.xml defines which field will go to the output XML.

The xsl file and output XML are like the following:

xsl file:

<xsl:template match="node()|@*">
<xsl:if test="(not(self::Field )or
@FieldName=document('requ*ired.xml')/*/FieldName">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>

output.xml

<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>

<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">


<Field fieldName="f6">Value6</Field>
</Group>
<Group name="G3">



</Group>
</AllFields>


How could I use XSLT to get the following desired output(without all
the empty lines and the last Group element:


<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f6">Value6</Field>
</Group>
</AllFields>


Thanks your help in advance!

 
Reply With Quote
 
 
 
 
Joris Gillis
Guest
Posts: n/a
 
      02-11-2005
Tempore 23:06:17, die Thursday 10 February 2005 AD, hinc in foro {comp.text.xml} scripsit <(E-Mail Removed)>:

> <xsl:template match="node()|@*">
> <xsl:if test="(not(self::Field )or
> @FieldName=document('requ*ired.xml')/*/FieldName">
> <xsl:copy>
> <xsl:apply-templates select="node()|@*"/>
> </xsl:copy>
> </xsl:if>
> </xsl:template>
>
> How could I use XSLT to get the following desired output(without all
> the empty lines and the last Group element:


try something like:

<xsl:template match="node()|@*">
<xsl:if test="not(self::Field or self::Group)
or (.|*)/@fieldName=document('requ*ired.xml')/*/FieldName">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>

(do beware of lower/uppercase, when you're testing this)

As for the whitespaces in your output, I don't see them occurring when I try your template.


regards,
--
Joris Gillis (http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
Veni, vidi, wiki (http://www.wikipedia.org)
 
Reply With Quote
 
 
 
 
ai2003lian@yahoo.com
Guest
Posts: n/a
 
      02-11-2005
Thank. But it didn't work. The result xml is as the following:

<?xml version="1.0"?>
<AllFields>



</AllFields>

Any ideas?


Joris Gillis wrote:
> Tempore 23:06:17, die Thursday 10 February 2005 AD, hinc in foro

{comp.text.xml} scripsit <(E-Mail Removed)>:
>
> > <xsl:template match="node()|@*">
> > <xsl:if test="(not(self::Field )or
> > @FieldName=document('requ*ired.xml')/*/FieldName">
> > <xsl:copy>
> > <xsl:apply-templates select="node()|@*"/>
> > </xsl:copy>
> > </xsl:if>
> > </xsl:template>
> >
> > How could I use XSLT to get the following desired output(without

all
> > the empty lines and the last Group element:

>
> try something like:
>
> <xsl:template match="node()|@*">
> <xsl:if test="not(self::Field or self::Group)
> or (.|*)/@fieldName=document('requ*ired.xml')/*/FieldName">
> <xsl:copy>
> <xsl:apply-templates select="node()|@*"/>
> </xsl:copy>
> </xsl:if>
> </xsl:template>
>
> (do beware of lower/uppercase, when you're testing this)
>
> As for the whitespaces in your output, I don't see them occurring

when I try your template.
>
>
> regards,
> --
> Joris Gillis

(http://www.ticalc.org/cgi-bin/acct-v...i?userid=38041)
> Veni, vidi, wiki (http://www.wikipedia.org)


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      02-11-2005
On 11 Feb 2005 07:19:08 -0800, <(E-Mail Removed)> wrote:

> Thank. But it didn't work. The result xml is as the following:
>
> <?xml version="1.0"?>
> <AllFields>
>
>
>
> </AllFields>
>
> Any ideas?
>


Very strange...

Tested with Saxon and AltovaXSLT

input:
<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f2">Value2</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f4">Value4</Field>
<Field fieldName="f5">Value5</Field>
<Field fieldName="f6">Value6</Field>
</Group>
<Group name="G3">
<Field fieldName="f7">Value7</Field>
<Field fieldName="f8">Value8</Field>
<Field fieldName="f9">Value9</Field>
</Group>
</AllFields>

required.xml:
<RequiredFields>
<FieldName>f1</FieldName>
<FieldName>f3</FieldName>
<FieldName>f6</FieldName>
</RequiredFields>

XSL:
<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">

<xsl:strip-space elements="*"/>
<xslutput method="xml" indent="yes"/>

<xsl:template match="node()|@*">
<xsl:if test="not(self::Field or self::Group)
or (.|*)/@fieldName=document('required.xml')/*/FieldName">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

(notice the 'strip-space' element I added; it solves the issue with the
linebreaks.

output:

<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f6">Value6</Field>
</Group>
</AllFields>


The stylesheet probably needed adaption to your real XML. It's probably
some wrong names in the test expression that cause the trouble with your
real XML.

--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
 
Reply With Quote
 
ai2003lian@yahoo.com
Guest
Posts: n/a
 
      02-11-2005
Thanks. It still didn't work for me since I'm using XML C parser
libxml2 and libxslt. But I came up with the following solution:

<xslutput method = "xml" indent = "yes" />

<xsl:template match="node()">
<xsl:if
test="descendant-or-self::*/@fieldName=document('required.xml')/*/FieldName
or @FieldName=document('requ*ired.xml')/*/FieldName">
<xsl:text>
</xsl:text>
<xsl:element name = "{name(self::*)}" >
<xsl:for-each select = "@*" >
<xsl:attribute name="{name(current())}" >
<xsl:value-of select = "current()" />
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
<xsl:value-of select = "node()" />
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

It works fine although I'm still looking for a better way to do it.


Joris Gillis wrote:
> On 11 Feb 2005 07:19:08 -0800, <(E-Mail Removed)> wrote:
>
> > Thank. But it didn't work. The result xml is as the following:
> >
> > <?xml version="1.0"?>
> > <AllFields>
> >
> >
> >
> > </AllFields>
> >
> > Any ideas?
> >

>
> Very strange...
>
> Tested with Saxon and AltovaXSLT
>
> input:
> <AllFields>
> <Group name="G1">
> <Field fieldName="f1">Value1</Field>
> <Field fieldName="f2">Value2</Field>
> <Field fieldName="f3">Value3</Field>
> </Group>
> <Group name="G2">
> <Field fieldName="f4">Value4</Field>
> <Field fieldName="f5">Value5</Field>
> <Field fieldName="f6">Value6</Field>
> </Group>
> <Group name="G3">
> <Field fieldName="f7">Value7</Field>
> <Field fieldName="f8">Value8</Field>
> <Field fieldName="f9">Value9</Field>
> </Group>
> </AllFields>
>
> required.xml:
> <RequiredFields>
> <FieldName>f1</FieldName>
> <FieldName>f3</FieldName>
> <FieldName>f6</FieldName>
> </RequiredFields>
>
> XSL:
> <xsl:stylesheet version="1.0"
> xmlnssl="http://www.w3.org/1999/XSL/Transform">
>
> <xsl:strip-space elements="*"/>
> <xslutput method="xml" indent="yes"/>
>
> <xsl:template match="node()|@*">
> <xsl:if test="not(self::Field or self::Group)
> or (.|*)/@fieldName=document('required.xml')/*/FieldName">
> <xsl:copy>
> <xsl:apply-templates select="node()|@*"/>
> </xsl:copy>
> </xsl:if>
> </xsl:template>
>
> </xsl:stylesheet>
>
> (notice the 'strip-space' element I added; it solves the issue with

the
> linebreaks.
>
> output:
>
> <AllFields>
> <Group name="G1">
> <Field fieldName="f1">Value1</Field>
> <Field fieldName="f3">Value3</Field>
> </Group>
> <Group name="G2">
> <Field fieldName="f6">Value6</Field>
> </Group>
> </AllFields>
>
>
> The stylesheet probably needed adaption to your real XML. It's

probably
> some wrong names in the test expression that cause the trouble with

your
> real XML.
>
> --
> Using Opera's revolutionary e-mail client: http://www.opera.com/m2/


 
Reply With Quote
 
Joris Gillis
Guest
Posts: n/a
 
      02-11-2005
On 11 Feb 2005 09:49:02 -0800, <(E-Mail Removed)> wrote:

> Thanks. It still didn't work for me since I'm using XML C parser
> libxml2 and libxslt. But I came up with the following solution:
>
> <xslutput method = "xml" indent = "yes" />
>
> <xsl:template match="node()">
> <xsl:if
> test="descendant-or-self::*/@fieldName=document('required.xml')/*/FieldName
> or @FieldName=document('requ*ired.xml')/*/FieldName">
> <xsl:text>
> </xsl:text>
> <xsl:element name = "{name(self::*)}" >
> <xsl:for-each select = "@*" >
> <xsl:attribute name="{name(current())}" >
> <xsl:value-of select = "current()" />
> </xsl:attribute>
> </xsl:for-each>
> <xsl:apply-templates select="node()"/>
> <xsl:value-of select = "node()" />
> </xsl:element>
> </xsl:if>
> </xsl:template>
> </xsl:stylesheet>
>
> It works fine although I'm still looking for a better way to do it.


how about this template?

<xsl:template match="node()">
<xsl:if
test="descendant-or-self::*/@fieldName=document('required.xml')/*/FieldName">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()"/>
<xsl:value-of select="text()" />
</xsl:copy>
</xsl:if>
</xsl:template>

(correct result in Saxon), just curious to know if your processor can
handle this...

--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
 
Reply With Quote
 
ai2003lian@yahoo.com
Guest
Posts: n/a
 
      02-11-2005
It did the trick! Thanks!

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Thread.current.parent and Thread.current.ancestors ara.t.howard@noaa.gov Ruby 3 02-16-2007 03:34 PM
JQuery and ancestors Yanick Javascript 4 12-31-2006 07:32 PM
Ancient Ancestors Old Gringo Computer Support 16 03-04-2005 09:23 PM
Multiply ancestors in xsl Martin Pettersson XML 2 10-18-2004 09:13 AM
XML: Collecting ancestors yurick XML 2 01-15-2004 08:16 AM



Advertisments