将XML嵌入XML以便在Web浏览器中显示:我做错了什么?

时间:2012-03-01 20:03:51

标签: xml xslt embed

所以我试着去研究这个问题,而且我几乎都在努力学习。我找到了一种在dpawson.co.uk上嵌入XML的方法, 但我无法弄清楚我做错了什么。我在互联网上搜寻试图寻找解决方案和解释,但似乎没有人有答案。

我正在尝试创建一个与服务器无关的文件,因此我可以向同事发送一个文件,希望他们可以通过在Web浏览器中打开文件来查看该文件。

到目前为止,这是我的代码:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!--Start XSL-->

<?xml-stylesheet type="text/xml" href="#stylesheet"?>

<!DOCTYPE doc [
<!ATTLIST xsl:stylesheet
id ID #REQUIRED>
]>
<doc>

<xsl:stylesheet id="stylesheet"
                version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="xsl:stylesheet" />
    <!--Variables-->
    <xsl:variable name="a" select="list/movie/seen[@value ='Yes']" />
    <xsl:variable name="b" select="list/movie/seen" />
    <xsl:variable name="c" select="sum(list/movie/rating/@value)" />
    <xsl:variable name="d" select="$c div count($a)" />
    <xsl:variable name="e" select="count($a) div count($b)" />
    <xsl:variable name="f" select="list/movie/seen[@value ='No']" />
    <xsl:variable name="g" select="list/movie/seen[@value ='Prior']" />
    <xsl:variable name="h" select="count($f) div count($b)" />
    <xsl:variable name="j" select="count($g) div count($b)" />
    <xsl:variable name="minutes_total" select="sum(list/movie/length[@value ='y'])" />
    <xsl:variable name="minutes" select="$minutes_total mod 60" />
    <xsl:variable name="hours" select="floor($minutes_total div 60) mod 24" />
    <xsl:variable name="hours2" select="floor($minutes_total div 60)" />
    <xsl:variable name="days" select="floor($hours2 div 24)" />
    <xsl:decimal-format name="percent" />
    <xsl:decimal-format name="average" decimal-separator="." />
    <!--End Variables-->
    <xsl:template match="/doc">
        <html>
            <head>
                <style>
                    h2{
                    font-family: Courier, Courier New, monospace;
                    font-size: 32px;
                    text-decoration: underline;
                    }
                    body{
                    font-family: Courier New, monospace;
                    }
                    p{
                    font-size: 16px;
                    }
                    table{
                    font-size: 14px;
                    }
                    .title{
                    text-align:left;
                    }
                    .release{
                    text-align:center;
                    }
                    .seen{
                    text-align:center;
                    }
                    .rating{
                    text-align:right;
                    }
                    .length{
                    text-align:center;
                    }
                </style>
            </head>
            <body>
                <h2>My Movie List</h2>
                <p>Movies seen so far: <xsl:value-of select="count($a)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($e, '#%', 'percent')" /><br />
                Movies yet to see: <xsl:value-of select="count($f)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($h, '#%', 'percent')" /><br />
                Movies seen prior to making list: <xsl:value-of select="count($g)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($j, '#%', 'percent')" /><br />
                Total time watched: <xsl:value-of select="format-number($days, '#0')" /> days, <xsl:value-of select="format-number($hours, '#0')" /> hours, <xsl:value-of select="format-number($minutes, '#0')" /> minutes<br />
                Average rating:  <xsl:value-of select="format-number($d, '#.000', 'average')" /> stars out of 5</p>
                <br />
                <table border="1">
                    <tr>
                        <th>#</th>
                        <th>Title</th>
                        <th>Release Date</th>
                        <th>Length</th>
                        <th>Seen</th>
                        <th>Rating</th>
                    </tr>
                    <xsl:for-each select="list/movie">
                        <xsl:choose>
                            <xsl:when test='seen = "Yes"'>
                                <tr style="background-color:#666; color:#fff">
                                    <td> <xsl:number /></td>
                                    <td class="title"><xsl:value-of select="title"/></td>
                                    <td class="release"><xsl:value-of select="release"/></td>
                                    <td class="length"><xsl:value-of select="length" /> minutes</td>
                                    <td class="seen"><xsl:value-of select="seen"/></td>
                                    <td class="rating"><xsl:value-of select="rating"/></td>
                                </tr>
                            </xsl:when>
                            <xsl:when test='seen = "Seen prior to making list"'>
                                <tr style="background-color:#999; color:#000">
                                    <td> <xsl:number /></td>
                                    <td class="title"><xsl:value-of select="title"/></td>
                                    <td class="release"><xsl:value-of select="release"/></td>
                                    <td class="length"><xsl:value-of select="length"/> minutes</td>
                                    <td class="seen"><xsl:value-of select="seen"/></td>
                                    <td class="rating"><xsl:value-of select="rating"/></td>
                                </tr>
                            </xsl:when>
                            <xsl:otherwise>
                                <tr style="background-color:#fff;">
                                    <td> <xsl:number /></td>
                                    <td class="title"><xsl:value-of select="title"/></td>
                                    <td class="release"><xsl:value-of select="release"/></td>
                                    <td class="length"><xsl:value-of select="length" /> minutes</td>
                                    <td class="seen"><xsl:value-of select="seen"/></td>
                                    <td class="rating"><xsl:value-of select="rating"/></td>
                                </tr>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
<!--Start XML-->
 <list>
    <movie>
        <title>2001: A Space Odyssey</title>
        <release>1968</release>
        <seen value="No">No</seen>
        <rating>N/A</rating>
        <length value="n">141</length>
    </movie>
    <movie>
        <title>28 Days Later</title>
        <release>2002</release>
        <seen value="No">No</seen>
        <rating>N/A</rating>
        <length value="n">113</length>
    </movie>
    <movie>
        <title>28 Weeks Later</title>
        <release>2007</release>
        <seen value="No">No</seen>
        <rating>N/A</rating>
        <length value="n">100</length>
    </movie>
    <movie>
        <title>A Clockwork Orange</title>
        <release>1971</release>
        <seen value="Yes">Yes</seen>
        <rating value="2">&#9734;&#9734;&#9734;&#9733;&#9733;</rating>
        <length value="y">136</length>
    </movie>
<!--Rest of XML-->
</list>
</doc>

这是一个电影列表,其中包含到目前为止我看过多少电影,有多少我尚未看到,有多少我在制作清单之前看到的,我投入的总时间看电影,看电影的平均评分。

问题在于所有变量都显示为零值,这会导致除以零,这也会在某些输出上产生NaN值。

任何人都可以提供的任何东西都将非常感谢!

1 个答案:

答案 0 :(得分:8)

以下代码:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="#stylesheet"?>
<!DOCTYPE doc [
<!ATTLIST xsl:stylesheet
id ID #REQUIRED>
]>
<doc>
 <!--Start XSL-->
 <xsl:stylesheet id="stylesheet"
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

  <xsl:template match="xsl:stylesheet" />

   <!--Variables-->
   <xsl:variable name="a" select="/doc/list/movie/seen[@value ='Yes']" />
   <xsl:variable name="b" select="/doc/list/movie/seen" />
   <xsl:variable name="c" select="sum(/doc/list/movie/rating/@value)" />
   <xsl:variable name="d" select="$c div count($a)" />
   <xsl:variable name="e" select="count($a) div count($b)" />
   <xsl:variable name="f" select="/doc/list/movie/seen[@value ='No']" />
   <xsl:variable name="g" select="/doc/list/movie/seen[@value ='Prior']" />
   <xsl:variable name="h" select="count($f) div count($b)" />
   <xsl:variable name="j" select="count($g) div count($b)" />
   <xsl:variable name="minutes_total" select="sum(/doc/list/movie/length[@value ='y'])" />
   <xsl:variable name="minutes" select="$minutes_total mod 60" />
   <xsl:variable name="hours" select="floor($minutes_total div 60) mod 24" />
   <xsl:variable name="hours2" select="floor($minutes_total div 60)" />
   <xsl:variable name="days" select="floor($hours2 div 24)" />
   <!--End Variables-->

  <xsl:decimal-format name="percent" />
  <xsl:decimal-format name="average" decimal-separator="." />

  <xsl:template match="/doc">
   <html>
    <head>
     <style>
      h2{
      font-family: Courier, Courier New, monospace;
      font-size: 32px;
      text-decoration: underline;
      }
      body{
      font-family: Courier New, monospace;
      }
      p{
      font-size: 16px;
      }
      table{
      font-size: 14px;
      }
      .title{
      text-align:left;
      }
      .release{
      text-align:center;
      }
      .seen{
      text-align:center;
      }
      .rating{
      text-align:right;
      }
      .length{
      text-align:center;
      }
     </style>
    </head>
    <body>
     <h2>My Movie List</h2>
     <p>Movies seen so far: <xsl:value-of select="count($a)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($e, '#%', 'percent')" /><br />
     Movies yet to see: <xsl:value-of select="count($f)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($h, '#%', 'percent')" /><br />
     Movies seen prior to making list: <xsl:value-of select="count($g)" />/<xsl:value-of select="count($b)" /> = <xsl:value-of select="format-number($j, '#%', 'percent')" /><br />
     Total time watched: <xsl:value-of select="format-number($days, '#0')" /> days, <xsl:value-of select="format-number($hours, '#0')" /> hours, <xsl:value-of select="format-number($minutes, '#0')" /> minutes<br />
     Average rating:  <xsl:value-of select="format-number($d, '#.000', 'average')" /> stars out of 5</p>
     <br />
     <table border="1">
      <tr>
       <th>#</th>
       <th>Title</th>
       <th>Release Date</th>
       <th>Length</th>
       <th>Seen</th>
       <th>Rating</th>
      </tr>
      <xsl:for-each select="list/movie">
       <xsl:choose>
        <xsl:when test='seen = "Yes"'>
         <tr style="background-color:#666; color:#fff">
          <td> <xsl:number /></td>
          <td class="title"><xsl:value-of select="title"/></td>
          <td class="release"><xsl:value-of select="release"/></td>
          <td class="length"><xsl:value-of select="length" /> minutes</td>
          <td class="seen"><xsl:value-of select="seen"/></td>
          <td class="rating"><xsl:value-of select="rating"/></td>
         </tr>
        </xsl:when>
        <xsl:when test='seen = "Seen prior to making list"'>
         <tr style="background-color:#999; color:#000">
          <td> <xsl:number /></td>
          <td class="title"><xsl:value-of select="title"/></td>
          <td class="release"><xsl:value-of select="release"/></td>
          <td class="length"><xsl:value-of select="length"/> minutes</td>
          <td class="seen"><xsl:value-of select="seen"/></td>
          <td class="rating"><xsl:value-of select="rating"/></td>
         </tr>
        </xsl:when>
        <xsl:otherwise>
         <tr style="background-color:#fff;">
          <td> <xsl:number /></td>
          <td class="title"><xsl:value-of select="title"/></td>
          <td class="release"><xsl:value-of select="release"/></td>
          <td class="length"><xsl:value-of select="length" /> minutes</td>
          <td class="seen"><xsl:value-of select="seen"/></td>
          <td class="rating"><xsl:value-of select="rating"/></td>
         </tr>
        </xsl:otherwise>
       </xsl:choose>
      </xsl:for-each>
     </table>
    </body>
   </html>
  </xsl:template>
 </xsl:stylesheet>

 <!--Start XML-->
 <list>
  <movie>
   <title>2001: A Space Odyssey</title>
   <release>1968</release>
   <seen value="No">No</seen>
   <rating>N/A</rating>
   <length value="n">141</length>
  </movie>
  <movie>
   <title>28 Days Later</title>
   <release>2002</release>
   <seen value="No">No</seen>
   <rating>N/A</rating>
   <length value="n">113</length>
  </movie>
  <movie>
   <title>28 Weeks Later</title>
   <release>2007</release>
   <seen value="No">No</seen>
   <rating>N/A</rating>
   <length value="n">100</length>
  </movie>
  <movie>
   <title>A Clockwork Orange</title>
   <release>1971</release>
   <seen value="Yes">Yes</seen>
   <rating value="2">&#9734;&#9734;&#9734;&#9733;&#9733;</rating>
   <length value="y">136</length>
  </movie>
  <!--Rest of XML-->
 </list>
</doc>

保存为XML文件并在FireFox Web浏览器中打开时,生成如下所示的所需输出。此处不显示格式,但是当您打开包含上述代码的XML文件时在FireFox中。

My Movie List

Movies seen so far: 1/4 = 25%  
Movies yet to see: 3/4 = 75%  
Movies seen prior to making list: 0/4 = 0%  
Total time watched: 0 days, 2 hours, 16 minutes  
Average rating: 2.000 stars out of 5  

# Title         Release Date    Length      Seen    Rating  
1 2001: A Space Odyssey 1968    141 minutes No      N/A  
2 28 Days Later         2002    113 minutes No      N/A  
3 28 Weeks Later        2007    100 minutes No      N/A  
4 A Clockwork Orange    1971    136 minutes Yes     ☆☆☆★★

注1:问题是在 <list> 元素中嵌入XML <doc> 导致的元素嵌套级别更改当您将XML和XSL放入单个文件格式时。该解决方案在/doc之前在所有XPath表达式中添加/list,以便选择现在嵌套在一个级别的所需元素更深层次的<doc> <list>的后代,而不仅仅是<list>的后代(就像两个文件分开时一样)。

注2:xml-stylesheet类型也改为“text / xsl”,作为与IE 8兼容的一步。使用“text / xml”类型,IE 8只显示文档树(包括XSL)作为XML,而使用“text / xsl”,它尝试 - 虽然相当不成功 - 应用转换。在IE 8中正确显示这个显示需要做更多的工作。请注意,任何类型的值在FireFox 7中都能正常工作。没有其他浏览器被测试过。