2015-05-12 2 views
1

Я следующий фрагмент 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, чтобы идентифицировать родителя элемента Name в view_mode tem плита выше, но без успеха. Может кто-нибудь дать некоторые предложения.

Заранее спасибо

ответ

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> 

Однако, это довольно неудобно. Более элегантное решение будет соответствовать по названию (как уже было предложено @Tirma), а также использовать стандартный шаблон значение атрибута:

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

спасибо Михаилу (и Tirma и Джоэл). Я понимаю, что итерация над элементом Name будет лучшим решением, но для понимания решения «name (.// Name/..)» означает, что мне нужно больше узнать об узлах и выражениях xpath. – BurnA

+0

@BurnA Выражение '.// Name/..' является аббревиатурой 'descendant :: Name/parent :: *', которая выбирает родительский элемент потомка с именем «Name». Теперь просто используйте это выражение как аргумент функции name(), чтобы получить имя этого элемента. –

1

использовать XSLT-2.0 ли? Учитывая хорошо сформированный XML, как это:

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

и XSLT-2,0 стилей, как это:

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

выводит:

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

Если перебирать Узлов типа Name вместо View, вам будет проще, потому что u может легко получить доступ к имени родительского узла, используя функцию name (..).

Вот код:

<xsl:template match="Name" > 
    <data name="objectName"> 
      <xsl:attribute name="value"> 
       <xsl:value-of select="concat(name(..), ':', .)"/> 
      </xsl:attribute> 
    </data> 
</xsl:template> 
Смежные вопросы