BurnA
BurnA

Reputation: 113

Working out parent element name

I have the following XML fragment

<View>
  <File>
    <Name>somefile_name</Name>
  </File>
</View>
<View>
<View>
  <Directory>
    <Name>somedirectory_name</Name>
  </Directory>
</View>
<View>
  <Pipe>
    <Name>somepipe_name</Name>
  </Pipe>
</View>

and the following xslt template

<xsl:template match="View" mode="view_mode" >
  <xsl:if test=".//Name" >
    <data name="objectName">
    <xsl:atribute name="value">
      <!-- I would like to prefix the object name with its type as per
           Directory:somedirectory_name. Each use of name() I have tried
           always results in matching the View element. What xpath can I use
           to gain the Name element's parent element name ie 'File', 'Pipe',
           or 'Directory'
      -->
      <xsl:value-of select=".//Name" />
    </xsl:atribute>
  </xsl:if>
</xsl:template>

My desired output, for the given input fragment above would be

<data name="objectName" value="File:somefile_name" />
<data name="objectName" value="Directory:somedirectory_name" />
<data name="objectName" value="Pipe:somepipe_name" />

I have been trying to work out the xpath to identify the parent of the Name element in the view_mode template above but without success. Can anyone provide some suggestions.

Thanks in advance

Upvotes: 1

Views: 56

Answers (3)

michael.hor257k
michael.hor257k

Reputation: 117073

Assuming XSLT 1.0, the quick fix for your issue would be to use:

<xsl:template match="View" mode="view_mode" >
    <xsl:if test=".//Name" >
        <data name="objectName">
            <xsl:attribute name="value">
                <xsl:value-of select="concat(name(.//Name/..), ':', .//Name)" />
            </xsl:attribute>
        </data>
    </xsl:if>
</xsl:template>

However, that is rather awkward. A more elegant solution would match on Name (as already suggested by @Tirma), and also use the attribute value template:

<xsl:template match="Name">
    <data name="objectName" value="{concat(name(..), ':', .)}"/>
</xsl:template>

Upvotes: 0

Tirma
Tirma

Reputation: 674

If you iterate through Nodes of type Name instead of View, its easier for you, because u can access easily to the parent node name using name(..) function.

Here is the code:

<xsl:template match="Name" >  
    <data name="objectName">
            <xsl:attribute name="value">
                <xsl:value-of select="concat(name(..), ':', .)"/>
            </xsl:attribute>
    </data>  
</xsl:template>

Upvotes: 0

Joel M. Lamsen
Joel M. Lamsen

Reputation: 7173

Do you use xslt-2.0? Given a well-formed xml like this:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<root>
    <View>
        <File>
            <Name>somefile_name</Name>
        </File>
    </View>
    <View>
        <Directory>
            <Name>somedirectory_name</Name>
        </Directory>
    </View>
    <View>
        <Pipe>
            <Name>somepipe_name</Name>
        </Pipe>
    </View>
</root>

and an xslt-2.0 stylesheet like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="root/View">
        <data name="objectName" value="{concat(.//Name/parent::*/name(), ':', .//Name)}"/>
    </xsl:template> 

</xsl:stylesheet>

it outputs:

<data name="objectName" value="File:somefile_name"/>
<data name="objectName" value="Directory:somedirectory_name"/>
<data name="objectName" value="Pipe:somepipe_name"/>

Upvotes: 1

Related Questions