1

I have an XML file with layout like this:

<root>
    <node>
        <descriptors>
            <attribute attr="important"/>
        </descriptors>
        <value>
            Some
        </value>
        <value>
            text
        </value>
        <value>
            here.
        </value>
    <node>
</root>

There are many nodes and each one is differentiated by the elements in the descriptors element. I need to extract the text so that I'd have this:

<element>
    Sometexthere.
</element>

I have an xsl transformation:

<xsl:template match="//attribute[@attr='important']">
    <element>
        <xsl:for-each select="../../value">
            <xsl:value-of select="." />
        </xsl:for-each>
    </element>
</xsl:template>

This instead just writes all the value elements in every node element in the file. I think I don't really understand the way scoping works (like when . points to the current element/node, but what is the current element/node in the loop).

How should I approach this?

EDIT

My actual xsl stylesheet (I'm transforming a docx file):

<xsl:template match="/">
        <order>
            <xsl:apply-templates/>
        </order>
    </xsl:template> 
    <xsl:template match="/w:document/w:body/w:p[w:pPr/w:pStyle/@w:val='Pealkiri1']">
        <name>
            <xsl:for-each select="w:t">
                <xsl:value-of select="." />
            </xsl:for-each>
        </name>
    </xsl:template>

1 Answer 1

2

You could try matching the node element that contains descriptors/attribute/@attr=... instead of the attribute element itself.

The for-each context would then be relative to that node.

<xsl:template match="/">
    <order>
        <xsl:apply-templates select="//node[descriptors/attribute/@attr='important']" />
    </order>
</xsl:template> 

<xsl:template match="node">
    <element>
        <xsl:for-each select="value">
            <xsl:value-of select="." />
        </xsl:for-each>
    </element>
</xsl:template>
Sign up to request clarification or add additional context in comments.

5 Comments

This produces the same result, but it omits the <element> tag. So now it's only text. Pretty weird.
Can you post the rest of your stylesheet? I guess you're missing <xsl:template match="/"> or are messing up an <xsl:apply-templates ...>.
I have the template matching /, but that just surrounds the text with my own root element (order).
The problem lies in your apply-templates: Without the select attribute, you will implicitely select all children. Since there were not templates defined, XSLT was using the default ones. The default templates always spew out the text but leave out the elements.
Okay, now I understand. This helped a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.