计算父元素名称

时间:2015-05-12 07:52:57

标签: xml xslt xpath

我有以下XML片段

<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>

以及以下xslt模板

<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>

我想要的输出,对于上面给定的输入片段将是

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

我一直试图找出xpath来识别上面view_mode模板中Name元素的父元素,但没有成功。任何人都可以提供一些建议。

提前致谢

3 个答案:

答案 0 :(得分:1)

你使用xslt-2.0吗?给出一个格式良好的xml:

<?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>

和像这样的xslt-2.0样式表:

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

输出:

{{1}}

答案 1 :(得分:0)

如果您遍历Name类型的节点而不是View,那么对您来说更容易,因为您可以使用name(..)函数轻松访问父节点名称。

以下是代码:

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

答案 2 :(得分:0)

假设XSLT 1.0,您的问题的快速解决方法是使用:

<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>

但是,这很尴尬。一个更优雅的解决方案将匹配Name(如@Tirma已经建议的那样),并且还使用属性值模板

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