2014-11-06 105 views
0

我正在開發XSLT轉換,它只能在XPath 1.0中使用xslt 1.0。 我們假設我有以下xml,並且我想選擇original_file_name屬性以「.prt」結尾的對象。我怎樣才能做到這一點?XPath/XSLT 1.0:基於子元素值標識元素

<object> 
    <object> 
     <attribute name="original_file_name">file1.qaf</attribute> 
     <attribute name="otherAttribute1">val</attribute> 
     <attribute name="otherAttribute2">val</attribute> 
    </object> 
    <object> 
     <attribute name="original_file_name">file2.tso</attribute> 
     <attribute name="otherAttribute1">Second guess</attribute> 
     <attribute name="otherAttribute2">val</attribute> 
    </object> 
    <object> 
     <attribute name="original_file_name">file3.prt</attribute> 
     <attribute name="otherAttribute1">First guess!</attribute> 
     <attribute name="otherAttribute2">val</attribute> 
    </object> 
</object> 

對於XSLT 2.0,我已經找到了解決方案,但我不能擺脫其XPath 1.0中不支持-的指數。你有任何提示解決方案嗎?

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
    <xsl:output method="xml" encoding="iso-8859-1" indent="yes"/> 
    <xsl:template match="/object"> 
     <xsl:variable name="fileIndex"> 
      <xsl:call-template name="identifyFile"> 
       <xsl:with-param name="fileNames" select="object/attribute[@name='original_file_name']"/> 
      </xsl:call-template> 
     </xsl:variable> 
     <xsl:variable name="fileObj" select="object[position()=$fileIndex]"/> 

     <!-- do sth. with fileObj --> 
     <xsl:copy-of select="$fileObj" /> 
    </xsl:template> 
    <xsl:template name="identifyFile"> 
     <xsl:param name="fileNames"/> 
     <xsl:choose> 
      <!-- add other file extensions here --> 
      <xsl:when test="$fileNames['.prt'=substring(., string-length() - 3)]"> 
       <xsl:value-of select="index-of($fileNames, $fileNames['.prt'=substring(., string-length() - 3)])" /> 
      </xsl:when> 
      <xsl:when test="$fileNames['.tso'=substring(., string-length() - 3)]"> 
       <xsl:value-of select="index-of($fileNames, $fileNames['.tso'=substring(., string-length() - 3)])" /> 
      </xsl:when> 
      <!-- if no known file extension has been found, just take the default one. --> 
      <xsl:otherwise> 
       <xsl:value-of select="1"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

編輯:在第一步中簡化了太多的問題:)。我添加了第二個文件擴展名,如果找不到第一個文件擴展名應該搜索。所以如果在這個例子中沒有'.prt'文件,應該採用'.tso'文件。

回答

1

如果你只是想選擇一個基於條件,那麼XPath表達式

object[attribute[@name='original_file_name' and substring(., string-length() - 3) = '.prt']] 
copy-of

應該足夠了。隨着你編輯的樣本,我想你只是想

<xsl:template match="/object"> 
    <xsl:variable name="fileNames" select="object/attribute[@name='original_file_name']"/> 
     <xsl:choose> 
      <!-- add other file extensions here --> 
      <xsl:when test="$fileNames['.prt'=substring(., string-length() - 3)]"> 
       <xsl:copy-of select="$fileNames['.prt'=substring(., string-length() - 3)]" /> 
      </xsl:when> 
      <xsl:when test="$fileNames['.tso'=substring(., string-length() - 3)]"> 
       <xsl:copy-of select="$fileNames['.tso'=substring(., string-length() - 3)]" /> 
      </xsl:when> 
      <!-- if no known file extension has been found, just take the default one. --> 
      <xsl:otherwise> 
       <xsl:copy-of select="$fileNames[1]"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
+0

謝謝你的建議!這會很簡單。我可能已經簡化了我最初的問題。但我一直在想,如果對於我真正的問題還有這樣一個單一的內容。還有什麼想法? – Mgmr 2014-11-06 16:10:32

+1

看來你知道如何選擇你想要的元素,而不是簡單地這樣做,你首先計算一個索引,然後根據索引返回。在這種情況下,您應該簡單地選擇並返回一步。我將編輯。 – 2014-11-06 17:03:43

+0

昨天我想出了這樣一個解決方案! :) 感謝您的幫助! – Mgmr 2014-11-07 07:42:18