Newbie again: position() doesn't return expected value

Y

Yereth

Hi again,

still working on my xslt program and I ran into another problem. There is a
file which a contains the following structure:

<key>1</key>
<dict>
...
</dict>
<key>2</key>
<dict>
..
</dict>

When I am in a "dict" tag I want to get the value from the key before it,
because they belong to eachother.. (don't ask me why it's constructed like
this, wasn't my work) Now I wrote the following code which should do the
job:

<xsl:template match="plist/dict">
<xsl:element name="playlist">
<xsl:for-each select="child::dict/dict">
<xsl:call-template name="track"/>
</xsl:for-each>
</xsl:element>
</xsl:template>

<xsl:template name="track">
<xsl:element name="track">
<xsl:variable name="pos" select="position()"/>
<xsl:apply-templates select="preceding-sibling::key[position()=$pos]"/>
<xsl:for-each select="child::key">
<xsl:call-template name="key_value"/>
</xsl:for-each>
</xsl:element>
</xsl:template>

Only, once pos has gained a value, it doesn't seem to get a new value in the
next round of the "for-each" loop.. is this a bug or am I making a mistake
in my thinking? Any help would be appreciated!

Thanks in advance,

Yereth
 
P

Peter Flynn

Yereth said:
Hi again,

still working on my xslt program and I ran into another problem. There is a
file which a contains the following structure:

<key>1</key>
<dict>
...
</dict>
<key>2</key>
<dict>
..
</dict>

When I am in a "dict" tag I want to get the value from the key before it,
select="preceding-sibling::key[1]"

because they belong to eachother.. (don't ask me why it's constructed like
this, wasn't my work) Now I wrote the following code which should do the
job:

<xsl:template match="plist/dict">
<xsl:element name="playlist">
<xsl:for-each select="child::dict/dict">
<xsl:call-template name="track"/>
</xsl:for-each>
</xsl:element>
</xsl:template>

<xsl:template name="track">
<xsl:element name="track">
<xsl:variable name="pos" select="position()"/>
<xsl:apply-templates select="preceding-sibling::key[position()=$pos]"/>
<xsl:for-each select="child::key">
<xsl:call-template name="key_value"/>
</xsl:for-each>
</xsl:element>
</xsl:template>

Only, once pos has gained a value, it doesn't seem to get a new value in the
next round of the "for-each" loop.. is this a bug or am I making a mistake
in my thinking? Any help would be appreciated!

Feature :) XSL[T] variables aren't variables as the term is used in a
procedural language. They take on their value once only for each
instantiation of their surrounding environment (and a for-each loop
is one instatiation, not N).

But you're not posting complete code. I don't see any template named
key_value here, so it's impossible to comment. Nor do I see any element
type called plist, nor and child of dict called dict. Etc.

Can you describe what you are trying to do? I *think* what you want is
to output a new track element within playlist for each dict element in
plist, using the value of the preceding key element as its content.

EG, given

<plist>
<key>1</key>
<dict>something</dict>
<key>2</key>
<dict>more</dict>
</plist>

you want

<playlist>
<track>1</track>
<track>2</track>
</playlist>

(unclear what you want to do with the content of each dict).

Don't use for-each unless you mean it. Let the document order do the
work if that's the order you want:

<xsl:template match="plist">
<playlist>
<xsl:apply-templates select="dict"/>
</playlist>
</xsl:template>

<xsl:template match="dict">
<track>
<xsl:value-of select="preceding-sibling::key[1]"/>
<!-- and presumably do something with the content as well -->
</track>
</xsl:template>

Be careful with position() if you are working without a Schema or DTD.
It doesn't refer only to element nodes: text nodes and white-space nodes
may also get counted.

///Peter
 
Y

Yereth Jansen

(Peter, sorry for replying to your e-mail address at first and not to the
group, my mistake)

Peter said:
When I am in a "dict" tag I want to get the value from the key
before it,

select="preceding-sibling::key[1]"

Ok, this worked for me. I thought I tried nearly everything yesterday,
including this, but I guess that wasn't the case.
But you're not posting complete code. I don't see any template named
key_value here, so it's impossible to comment. Nor do I see any
element
type called plist, nor and child of dict called dict. Etc.

Maybe I should've been a bit more clear, because it is mentioned in the
code, but these things are nog relevant to the current problem. Your
assumption below is correct en within the dict there are more
<key>track_name</key><string>this is the track name</string> values. These
are not relevant to the problem either. What I couldn't get to work was have
the value from the key that was before the dict value.
EG, given

<plist>
<key>1</key>
<dict>something</dict>
<key>2</key>
<dict>more</dict>
</plist>

you want

<playlist>
<track>1</track>
<track>2</track>
</playlist>
Indeed.

Be careful with position() if you are working without a Schema or DTD.
It doesn't refer only to element nodes: text nodes and white-space
nodes
may also get counted.

It is still not exactly clear to me what some functions exactly do and to
what they apply sometimes. I'd like xslt to be a little more explicit, but
that's maybe because I'm really more an OO programmer.

Thank you very much for your help. And my appologies for the double post.
Guess the newsserver is not always as fast as I want it to be.

Yereth
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top