2010-12-20 55 views
0

我有這個格式的XML文件:在兄弟節點使用XSL XSLT困惑:應用模板

<?xml version="1.0" encoding="utf-8" ?> 
<OpacResult> 
<valueObjects class="list"> 
    <Catalog> 
     <notes> 
      Daily newsletter available via e-mail.&#xd; 
      IP authenticated. Login not needed within firm. 
     </notes> 
     <title>Health law360. </title> 
     <url>http://health.law360.com/</url> 
     <catalogTitles class="list"> 
      <CatalogTitle> 
       <uuid>e5e2bc53ac1001f808cddc29f93ecad8</uuid> 
       <timeChanged class="sql-timestamp">2010-12-14 09:17:10.707</timeChanged> 
       <timeEntered class="sql-timestamp">2010-12-14 09:17:10.707</timeEntered> 
       <whoChanged>B23DE2FFE8DD49B0B0A03D1FEB3E7DA2</whoChanged> 
       <whoEntered>B23DE2FFE8DD49B0B0A03D1FEB3E7DA2</whoEntered> 
       <updateSearchIndex>true</updateSearchIndex> 
       <corpId>RopesGray</corpId> 
       <catalogUuid>a20b6b4bac1001f86d28280ed0ebeb9e</catalogUuid> 
       <type>O</type> 
       <title>Law 360. Health law.</title> 
      </CatalogTitle> 
      <CatalogTitle> 
       <uuid>e5e2bc53ac1001f808cddc299ddfe49d</uuid> 
       <timeChanged class="sql-timestamp">2010-12-14 09:17:10.707</timeChanged> 
       <timeEntered class="sql-timestamp">2010-12-14 09:17:10.707</timeEntered> 
       <whoChanged>B23DE2FFE8DD49B0B0A03D1FEB3E7DA2</whoChanged> 
       <whoEntered>B23DE2FFE8DD49B0B0A03D1FEB3E7DA2</whoEntered> 
       <updateSearchIndex>true</updateSearchIndex> 
       <corpId>RopesGray</corpId> 
       <catalogUuid>a20b6b4bac1001f86d28280ed0ebeb9e</catalogUuid> 
       <type>O</type> 
       <title>Health law 360</title> 
      </CatalogTitle> 
      <CatalogTitle> 
       <uuid>e5e2bc53ac1001f808cddc29ec1d959b</uuid> 
       <timeChanged class="sql-timestamp">2010-12-14 09:17:10.707</timeChanged> 
       <timeEntered class="sql-timestamp">2010-12-14 09:17:10.707</timeEntered> 
       <whoChanged>B23DE2FFE8DD49B0B0A03D1FEB3E7DA2</whoChanged> 
       <whoEntered>B23DE2FFE8DD49B0B0A03D1FEB3E7DA2</whoEntered> 
       <updateSearchIndex>true</updateSearchIndex> 
       <corpId>RopesGray</corpId> 
       <catalogUuid>a20b6b4bac1001f86d28280ed0ebeb9e</catalogUuid> 
       <type>O</type> 
       <title>Health law three hundred sixty</title> 
      </CatalogTitle> 
     </catalogTitles> 
     <catalogUrls class="list"/> 
     <gmd> 
      <uuid>f8f123acc0a816070192e296a6a71715</uuid> 
      <timeChanged class="sql-timestamp">2006-10-10 15:23:37.813</timeChanged> 
      <timeEntered class="sql-timestamp">2005-01-27 00:00:00.0</timeEntered> 
      <whoChanged>25db9fcd3fd247f4a20485b40cc134ad</whoChanged> 
      <whoEntered>user</whoEntered> 
      <updateSearchIndex>true</updateSearchIndex> 
      <corpId>RopesGray</corpId> 
      <isRuleDefault>false</isRuleDefault> 
      <ruleName>text</ruleName> 
      <term>electronic resource</term> 
      <preferCollection>false</preferCollection> 
      <isTechnicalManual>false</isTechnicalManual> 
      <sip2IsMagnetic>false</sip2IsMagnetic> 
     </gmd> 
     <issues class="list"/> 
    </Catalog> 
</valueObjects> 
</OpacResult> 

正如你所看到的,還有其他的元素,但我不在乎這些,只想看第一個。

我使用這個代碼來調用與所需的元素作爲參數 並通過星號分隔字符串參數模板循環的字符串的模板:(標題* URL *注*)

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:param name="columns" /> 
<xsl:template match="/OpacResult/valueObjects"> 
    <html> 
     <body> 
      <table border="1"> 

       <!-- Header row --> 
       <tr> 
        <xsl:call-template name="print-headers"> 
         <xsl:with-param name="columns" select="$columns"/> 
        </xsl:call-template> 
       </tr> 

       <!-- Value rows --> 
       <xsl:for-each select="Catalog"> 
        <tr> 
         <xsl:call-template name="print-values"> 
          <xsl:with-param name="columns" select="$columns"/> 
         </xsl:call-template> 
        </tr> 
       </xsl:for-each> 
      </table> 
     </body> 
    </html> 
</xsl:template> 

<!-- Split up string of column names and create header field names based on element names--> 
<xsl:template name="print-headers"> 
    <xsl:param name="columns"/> 

    <xsl:variable name="newList" select="$columns"/> 
    <xsl:variable name="first" select="substring-before($newList, '*')" /> 
    <xsl:variable name="remaining" select="substring-after($newList, '*')" /> 

    <th> 
     <xsl:apply-templates select="Catalog/*[name()=$first]"> 
      <xsl:with-param name="header">true</xsl:with-param> 
     </xsl:apply-templates> 
    </th> 

    <xsl:if test="$remaining"> 
     <xsl:call-template name="print-headers"> 
      <xsl:with-param name="columns" select="$remaining"/> 
     </xsl:call-template> 
    </xsl:if> 

</xsl:template> 

<xsl:template name="print-values"> 
    <xsl:param name="columns"/> 

    <xsl:variable name="newList" select="$columns"/> 
    <xsl:variable name="first" select="substring-before($newList, '*')" /> 
    <xsl:variable name="remaining" select="substring-after($newList, '*')" /> 

    <td> 
     <xsl:apply-templates select="Catalog/*[name()=$first]"/> 
    </td> 

    <xsl:if test="$remaining"> 
     <xsl:call-template name="print-values"> 
      <xsl:with-param name="columns" select="$remaining"/> 
     </xsl:call-template> 
    </xsl:if> 

</xsl:template> 

<xsl:template match="title"> 
    <xsl:param name="header"/> 

    <xsl:choose> 
     <xsl:when test="$header='true'"> 
      <xsl:text>Title</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <a> 
       <xsl:attribute name="href"> 
        <xsl:value-of select="//*[name()='url']"/> 
       </xsl:attribute> 
       <xsl:value-of select="//*[name()='title']"/> 
      </a> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="url"> 
    <xsl:param name="header"/> 

    <xsl:choose> 
     <xsl:when test="$header='true'"> 
      <xsl:text>URL</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <a> 
       <xsl:attribute name="href"> 
        <xsl:value-of select="//*[name()='url']"/> 
       </xsl:attribute> 
       <xsl:value-of select="//*[name()='url']"/> 
      </a> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="notes"> 
    <xsl:param name="header"/> 

    <xsl:choose> 
     <xsl:when test="$header='true'"> 
      <xsl:text>Notes</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="//*[name()='notes']"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="holdingNotes"> 
    <xsl:param name="header"/> 

    <xsl:choose> 
     <xsl:when test="$header='true'"> 
      <xsl:text>Holding Notes</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="//*[name()='holdingNotes']"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="relatedUrl"> 
    <xsl:param name="header"/> 

    <xsl:choose> 
     <xsl:when test="$header='true'"> 
      <xsl:text>Related URL</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="//*[name()='relatedUrl']"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="bibliographicType/hasDataFile"> 
    <xsl:param name="header"/> 

    <xsl:choose> 
     <xsl:when test="$header='true'"> 
      <xsl:text>File</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="Catalog/*[name()='hasDataFile']"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

我可以訪問此模板的唯一方法是使用// * [name()= $ first]語法根據$ first參數中的名稱提取元素的值。

任何幫助,非常感謝。首先十分感謝。不包括完整的XML,因爲有成千上萬行不必要的文本。

+4

有13個問題,只有一個答案被接受,只有三個投票。是的,我不會浪費我的時間在你身上。 – 2010-12-20 21:14:02

+0

沒有提供完整的xml文檔或完整的xslt代碼。你如何期待有人甚至能夠重現你的問題? – 2010-12-20 21:20:40

+1

我不確定你想要的輸出是什麼。另外,url,notes元素在XML中的位置是什麼?他們是Catalog,catalogTitles還是catalogTitle的孩子? – JST 2010-12-20 21:22:20

回答

1

該樣式表:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:h="header" 
exclude-result-prefixes="h"> 
    <h:h> 
     <title>Title</title> 
     <url>URL</url> 
     <notes>Notes</notes> 
    </h:h> 
    <xsl:param name="pColumns" select="'title url notes'"/> 
    <xsl:template match="/OpacResult/valueObjects"> 
     <html> 
      <body> 
       <table border="1"> 
        <tr> 
         <xsl:apply-templates 
          select="document('')/*/h:h" 
          mode="filter"/> 
        </tr> 
        <xsl:apply-templates/> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
    <xsl:template match="Catalog"> 
     <tr> 
      <xsl:call-template name="filter"/> 
     </tr> 
    </xsl:template> 
    <xsl:template match="h:h/*"> 
     <th> 
      <xsl:value-of select="."/> 
     </th> 
    </xsl:template> 
    <xsl:template match="Catalog/*"> 
     <td> 
      <xsl:value-of select="."/> 
     </td> 
    </xsl:template> 
    <xsl:template match="node()" mode="filter" name="filter"> 
     <xsl:apply-templates select="*[contains(
              concat(' ',$pColumns,' '), 
              concat(' ',name(),' '))]"> 
      <xsl:sort select="substring-before(
           concat(' ',$pColumns,' '), 
           concat(' ',name(),' '))"/> 
     </xsl:apply-templates> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<html> 
    <body> 
     <table border="1"> 
      <tr> 
       <th>Title</th> 
       <th>URL</th> 
       <th>Notes</th> 
      </tr> 
      <tr> 
       <td>Health law360. </td> 
       <td>http://health.law360.com/</td> 
       <td>    Daily newsletter available via e-mail. 
      IP authenticated. Login not needed within firm.   </td> 
      </tr> 
     </table> 
    </body> 
</html> 

:用於報頭內聯數據,用於過濾和排序的僞序列參數,模式不用於處理不同的方式相同的元件但也用於以相同的方式處理不同的元素。

+0

非常感謝您的回覆正確顯示數據。我仍然在學習XSLT,所以我不熟悉你在這裏使用的所有標籤。然而,這個應用程序的目標(我之前應該提到過)是爲了避免在任何地方引用列的名稱,只需構建標題行並填寫數據,僅給出調用列的名稱碼。 – 2010-12-29 15:04:13

+0

@Music Magi:從您的問題或樣式表中不清楚。爲此,您可以傳遞元素名稱並將其大小寫形式用於標題,而不是將我的內聯數據與樣式表意向對齊。 – 2010-12-29 20:43:25

0

我找到了一個解決方案,但我確定這不是最好的方法。在每一個我預計領域的模板,我說:

<xsl:if test=position()=1"> 
    .. process data here .. 
</xsl:if> 

理想的情況下,將有一個方法告訴這僅處理第一個元素髮現:

<th> 
    <xsl:apply-templates select="//*[name()=$first]"> 
     <xsl:with-param name="header">true</xsl:with-param> 
    </xsl:apply-templates> 
</th> 

編輯:我懷疑,當有多個目錄元素需要解析時,這不起作用。因此,不是爲每個目錄父元素抓取第一個元素,而是每次抓取文檔中的第一個元素

+1

你的絕對錶達式'// * [name()='notes']'會在整個文檔中選擇名爲「notes」的每個元素(而不僅僅是上下文中的'Catalog'的子元素) – 2010-12-29 20:40:41