簡體   English   中英

使用xslt轉換嵌套的子節點

[英]Transforming nested child nodes with xslt

XML數據文件

<?xml version="1.0" encoding="utf-8"?>
<page>
    <tab dim="70">

        <tab dim="50">
        alpha

        </tab>
        <tab dim="50">
        alpha

        </tab>

    </tab>
    <tab dim="30">
        gama
    </tab>
</page>

XSLT文件

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

<xsl:output method="xml" version="1.0"
encoding="iso-8859-1" indent="yes"/>

<xsl:template match="/">
    <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html&gt;</xsl:text>
    <html>
    <head>
        <title>Title</title>
        <link type="text/css" href="/css/framework.css" rel="stylesheet"/>

    </head>
    <body>
    <div id="page-base">
        <xsl:for-each select="//tab">
        <div class="wrapper tab">
            <xsl:attribute name="style"> 
                width:<xsl:value-of select="@dim" />%;
                min-width:<xsl:value-of select="@dim" />%;
                max-width:<xsl:value-of select="@dim" />%;
            </xsl:attribute>
            <xsl:value-of select="." />
        </div>
        </xsl:for-each>
    </div>
    </body>
    </html>
</xsl:template>

</xsl:stylesheet>

輸出繼電器

<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="/css/framework.css" type="text/css">
</head>
<body>
<div id="page-base">
 <div class="wrapper tab" style=" width:70%; min-width:70%; max-width:70%; ">
   alpha alpha   
 </div>
 <div class="wrapper tab" style=" width:50%; min-width:50%; max-width:50%; "> alpha </div>
 <div class="wrapper tab" style=" width:50%; min-width:50%; max-width:50%; "> alpha </div>
 <div class="wrapper tab" style=" width:30%; min-width:30%; max-width:30%; "> gama </div>
</div>
</body>

期望的輸出

<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="/css/framework.css" type="text/css">
</head>
<body>
<div id="page-base">
 <div class="wrapper tab" style=" width:70%; min-width:70%; max-width:70%; ">
  <div class="wrapper tab" style=" width:50%; min-width:50%; max-width:50%; "> alpha </div>
  <div class="wrapper tab" style=" width:50%; min-width:50%; max-width:50%; "> alpha </div>
 </div>
 <div class="wrapper tab" style=" width:30%; min-width:30%; max-width:30%; "> gama </div>
</div>
</body>
</html>

關鍵是不要使用<xsl:for-each> 請改用模板匹配。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="/">
    <html>
      <head>
        <title>Title</title>
        <link type="text/css" href="/css/framework.css" rel="stylesheet"/>
      </head>
      <body>
        <xsl:apply-templates />
      </body>
    </html>
  </xsl:template>

  <xsl:template match="page">
    <div id="page-base">
      <xsl:apply-templates />
    </div>
  </xsl:template>

  <xsl:template match="tab">
    <div class="wrapper tab" style="width:{@dim}%; min-width:{@dim}%; max-width:{@dim}%;">
      <xsl:apply-templates />
    </div>
  </xsl:template>
</xsl:stylesheet>

結果:(另見http://xsltransform.net/gWmuiK6

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Title</title>
      <link type="text/css" href="/css/framework.css" rel="stylesheet">
   </head>
   <body>
      <div id="page-base">
         <div class="wrapper tab" style="width:70%; min-width:70%; max-width:70%;">
            <div class="wrapper tab" style="width:50%; min-width:50%; max-width:50%;">
               alpha


            </div>
            <div class="wrapper tab" style="width:50%; min-width:50%; max-width:50%;">
               alpha


            </div>
         </div>
         <div class="wrapper tab" style="width:30%; min-width:30%; max-width:30%;">
            gama

         </div>
      </div>
   </body>
</html>

要擺脫輸出中的空白區域,您需要做的就是添加另一個模板:

<xsl:template match="tab/text()">
  <xsl:value-of select="normalize-space()" />
</xsl:template>

在某些特定情況下, <xsl:for-each>是正確的選擇。 這不是其中的一個。

每當你傾向於使用<xsl:for-each>你應該停下來思考。 在絕大多數情況下, <xsl:apply-templates>是您真正想要的。

僅當您找到針對 <xsl:apply-templates>的令人信服的理由時才使用<xsl:for-each> <xsl:apply-templates> 如果你想不出一個這樣的理由,那么可能就沒有了。


要輸出顯示在輸入中的節點而不更改它們,請添加標識模板:

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()" />
  </xsl:copy>
</xsl:template>

要將輸出中不需要的節點靜音,請添加一個空模板:

<xsl:template match="node/to/match" />

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM