1

因此,我正在阅读 w3schools 上的 XML 教程,并且遇到了有关使用 XSLT 设置 XML 样式的页面: http ://www.w3schools.com/xml/tryxslt.asp?xmlfile=simple&xsltfile=simple

那里有一些简单的代码。我在代码中添加了两个主要的食物类别<waffles><other> 我想知道如何使用最小的 XSLT 来设置 XML 的样式,以便所有<waffle> <food>的都有橙色背景和<other><food>青色背景,而不必重复一大块像我在下面做的代码。

您可以在上面的链接中看到原始代码,这是我的代码:

XML:

    <?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<breakfast_menu>
     <waffles>
    <food>
        <name>Belgian Waffles</name>
        <price>$5.95</price>
        <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
        <calories>650</calories>
    </food>
    <food>
        <name>Strawberry Belgian Waffles</name>
        <price>$7.95</price>
        <description>light Belgian waffles covered with strawberries and whipped cream</description>
        <calories>900</calories>
    </food>
    <food>
        <name>Berry-Berry Belgian Waffles</name>
        <price>$8.95</price>
        <description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
        <calories>900</calories>
    </food>
     </waffles>
     <other>
    <food>
        <name>French Toast</name>
        <price>$4.50</price>
        <description>thick slices made from our homemade sourdough bread</description>
        <calories>600</calories>
    </food>
    <food>
        <name>Homestyle Breakfast</name>
        <price>$6.95</price>
        <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
        <calories>950</calories>
    </food>
     <other>
</breakfast_menu>

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
    <html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
      <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
    <xsl:for-each select="breakfast_menu/waffles">
        <div style="background-color:ORANGE;">
          <xsl:for-each select="food">
          <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold"><xsl:value-of select="name"/></span>
            - <xsl:value-of select="price"/>
          </div>
          <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
            <xsl:value-of select="description"/>
            <span style="font-style:italic">
              <xsl:value-of select="calories"/> (calories per serving)
            </span>
          </div>
         </xsl:for-each>
       </div>    
    </xsl:for-each>

    <xsl:for-each select="breakfast_menu/other">
        <div style="background-color:CYAN;">
          <xsl:for-each select="food">
          <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold"><xsl:value-of select="name"/></span>
            - <xsl:value-of select="price"/>
          </div>
          <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
            <xsl:value-of select="description"/>
            <span style="font-style:italic">
              <xsl:value-of select="calories"/> (calories per serving)
            </span>
          </div>
         </xsl:for-each>
       </div>    
    </xsl:for-each>

      </body>
    </html>
4

2 回答 2

1

在这里您可以利用模板的强大功能,这是 XSLT 最基本的概念之一。

您可以从寻找早餐菜单元素的子元素开始

<xsl:apply-templates select="breakfast_menu/*"/>

然后你会有一个模板来匹配这些元素

<xsl:template match="breakfast_menu/*">

在此模板中,您可以使用xsl:choose创建样式属性

  <div>
     <xsl:attribute name="style">
        <xsl:choose>
           <xsl:when test="local-name() = 'waffles'">background-color:ORANGE;</xsl:when>
           <xsl:when test="local-name() = 'other'">background-color:CYAN;</xsl:when>
        </xsl:choose>
     </xsl:attribute>

在这种情况下,这是完整的 XSLT。注意也使用模板来匹配食物元素以避免使用xsl:for-each

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>
   <xsl:template match="/">
      <html>
         <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
            <xsl:apply-templates select="breakfast_menu/*"/>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="breakfast_menu/*">
      <div>
         <xsl:attribute name="style">
            <xsl:choose>
               <xsl:when test="local-name() = 'waffles'">background-color:ORANGE;</xsl:when>
               <xsl:when test="local-name() = 'other'">background-color:CYAN;</xsl:when>
            </xsl:choose>
         </xsl:attribute>
         <xsl:apply-templates select="food"/>
      </div>
   </xsl:template>

   <xsl:template match="food">
      <div style="background-color:teal;color:white;padding:4px">
         <span style="font-weight:bold">
            <xsl:value-of select="name"/>
         </span> - 
         <xsl:value-of select="price"/></div>
      <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
         <xsl:value-of select="description"/>
         <span style="font-style:italic">
            <xsl:value-of select="calories"/> (calories per serving) </span>
      </div>
   </xsl:template>
</xsl:stylesheet>

避免使用xsl:choose的另一种稍微不同的方法是使用单独的模板来匹配您的华夫饼其他元素。只需将当前匹配“breakfast_menu/*”的模板替换为以下两个模板即可。

<xsl:template match="breakfast_menu/waffles">
  <div style="background-color:ORANGE;">
     <xsl:apply-templates select="food"/>
  </div>
</xsl:template>

<xsl:template match="breakfast_menu/other">
  <div style="background-color:CYAN;">
     <xsl:apply-templates select="food"/>
  </div>
</xsl:template>

如果你有很多子元素,但想要一个默认的“值”,你可以做这样的事情

<xsl:template match="breakfast_menu/waffles" priority="2">
  <div style="background-color:ORANGE;">
     <xsl:apply-templates select="food"/>
  </div>
</xsl:template>

<xsl:template match="breakfast_menu/*" priority="1">
  <div style="background-color:CYAN;">
     <xsl:apply-templates select="food"/>
  </div>
</xsl:template>

注意在这种情况下优先级属性的使用,因为否则两个模板都会匹配waffle 。这将是一个错误,除非您告诉 XSLT 处理器一个比另一个具有更高的优先级。

于 2012-09-14T08:00:45.127 回答
0

这种转变

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:colors>
  <color>ORANGE</color>
  <color>CYAN</color>
 </my:colors>

 <xsl:variable name="vColors" select="document('')/*/my:colors/*"/>

 <xsl:template match="/">
    <html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
      <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
      <xsl:apply-templates/>
      </body>
    </html>
 </xsl:template>

 <xsl:template match="*[food]">
        <div style="background-color:{$vColors[2 -(name(current())='waffles')]};">
          <xsl:for-each select="food">
          <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold"><xsl:value-of select="name"/></span>
            - <xsl:value-of select="price"/>
          </div>
          <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
            <xsl:value-of select="description"/>
            <span style="font-style:italic">
              <xsl:value-of select="calories"/> (calories per serving)
            </span>
          </div>
         </xsl:for-each>
       </div>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<breakfast_menu>
     <waffles>
    <food>
        <name>Belgian Waffles</name>
        <price>$5.95</price>
        <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
        <calories>650</calories>
    </food>
    <food>
        <name>Strawberry Belgian Waffles</name>
        <price>$7.95</price>
        <description>light Belgian waffles covered with strawberries and whipped cream</description>
        <calories>900</calories>
    </food>
    <food>
        <name>Berry-Berry Belgian Waffles</name>
        <price>$8.95</price>
        <description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
        <calories>900</calories>
    </food>
     </waffles>
     <other>
    <food>
        <name>French Toast</name>
        <price>$4.50</price>
        <description>thick slices made from our homemade sourdough bread</description>
        <calories>600</calories>
    </food>
    <food>
        <name>Homestyle Breakfast</name>
        <price>$6.95</price>
        <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
        <calories>950</calories>
    </food>
     </other>
</breakfast_menu>

产生想要的正确结果:

<html xmlns="http://www.w3.org/1999/xhtml">
   <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
      <div xmlns="" style="background-color:ORANGE;">
         <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold">Belgian Waffles</span>
            - $5.95</div>
         <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">two of our famous Belgian Waffles with plenty of real maple syrup<span style="font-style:italic">650 (calories per serving)
            </span>
         </div>
         <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold">Strawberry Belgian Waffles</span>
            - $7.95</div>
         <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">light Belgian waffles covered with strawberries and whipped cream<span style="font-style:italic">900 (calories per serving)
            </span>
         </div>
         <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold">Berry-Berry Belgian Waffles</span>
            - $8.95</div>
         <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">light Belgian waffles covered with an assortment of fresh berries and whipped cream<span style="font-style:italic">900 (calories per serving)
            </span>
         </div>
      </div>
      <div xmlns="" style="background-color:CYAN;">
         <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold">French Toast</span>
            - $4.50</div>
         <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">thick slices made from our homemade sourdough bread<span style="font-style:italic">600 (calories per serving)
            </span>
         </div>
         <div style="background-color:teal;color:white;padding:4px">
            <span style="font-weight:bold">Homestyle Breakfast</span>
            - $6.95</div>
         <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">two eggs, bacon or sausage, toast, and our ever-popular hash browns<span style="font-style:italic">950 (calories per serving)
            </span>
         </div>
      </div>
   </body>
</html>

说明

正确使用:

  1. 模板匹配。

  2. AVT(属性值模板)。

于 2012-09-14T13:08:40.843 回答