问题从XML创建XSL文件期间

时间:2013-01-22 05:16:50

标签: xml xslt xsd xquery

我有一个像这样的表结构

----------------------------------
id    |    name       | parent_id
------------------------------------
1     | root_category | Null
2     | Appare        | 1
3     | Accessories   | 1
4     | Shirt         | 2
5     | Pants         | 2
6     | hand Bags     | 3
7     | jewelry       | 3
从这张表中我创建了一个XML文件,就像这个test.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<childrens>
  <child id="1" value="Root Catalog" parent_id="0">
    <child id="2" value="Apparel" parent_id="1">
      <child id="4" value="Shirts" parent_id="2"/>
      <child id="5" value="Pants" parent_id="2"/>
    </child>
    <child id="3" value="Accessories" parent_id="1">
      <child id="6" value="Handbags" parent_id="3"/>
      <child id="7" value="Jewelry" parent_id="3"/>
    </child>
  </child>
</childrens>

使用这个xml文件,我创建了一个类似于test.xsl

的XSL文件
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<h2>Testing</h2>
  <table border="1">
   <tr bgcolor="#9acd32">
    <th>Id </th>
    <th>Name</th>
  </tr>
  <xsl:for-each select="childrens/child">
  <tr>
    <td><xsl:value-of select="@id"/></td>
    <td><xsl:value-of select="@value"/></td>
  </tr>
  </xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

但它不起作用且没有显示数据

数据应该看起来像

Root Category
 - Apparel 
   -- Shirts
   -- Pants 
 - Accessories
   -- Handbags 
  -- Jewelry

2 个答案:

答案 0 :(得分:1)

我不完全确定您期望的输出。您当前的XSLT正在输出一个表,但您的示例看起来更像是嵌套列表。如果您确实想要显示元素的层次结构,那么嵌套列表可能就是这样。

通过单个模板匹配元素,然后递归调用自身,这是相对简单的。

   <xsl:template match="child">
      <li>
         <xsl:value-of select="@value"/>
         <xsl:if test="child">
            <ul>
               <xsl:apply-templates select="child"/>
            </ul>
         </xsl:if>
      </li>
   </xsl:template>

即。输出 li 元素,如果元素本身有子元素,则在其中启动一个新的 ul 元素。

这是完整的XSLT

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

   <xsl:template match="/childrens">
      <html>
         <body>
            <ul>
               <xsl:apply-templates select="child"/>
            </ul>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="child">
      <li>
         <xsl:value-of select="@value"/>
         <xsl:if test="child">
            <ul>
               <xsl:apply-templates select="child"/>
            </ul>
         </xsl:if>
      </li>
   </xsl:template>
</xsl:stylesheet>

当应用于您的示例XML时,输出以下内容

<html>
   <body>
      <ul>
         <li>Root Catalog
            <ul>
               <li>Apparel
                  <ul>
                     <li>Shirts</li>
                     <li>Pants</li>
                  </ul>
               </li>
               <li>Accessories
                  <ul>
                     <li>Handbags</li>
                     <li>Jewelry</li>
                  </ul>
               </li>
            </ul>
         </li>
      </ul>
   </body>
</html>

在视觉上将如下所示

  • 根目录
    • 服装
      • 衬衫
      • 裤子
    • 配件
      • 手袋
      • 珠宝

编辑:正如JLRishie在评论中所提到的(谢谢!),如果您想在 li 元素中包含ID属性,请执行以下操作:

<li id="{@id}">

答案 1 :(得分:1)

I.T。,

我尝试做一个执行文本输出的XSLT。我添加了换行符和制表符来获取所请求的结构。我强烈建议您更改XML,并将元素命名为与孩子不同的元素,在我看来更容易使用。但这只是一个建议。

应用此XSLT:

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

<xsl:output method="text"/>

<xsl:variable name="lf" select="'&#x0A;'"/>
<xsl:variable name="tab" select="'&#x09;'"/>

<xsl:template match="/">
    <xsl:text>Root Category</xsl:text>
    <xsl:apply-templates/>
</xsl:template>

<!-- match the apparel -->
<xsl:template match="child[@value='Apparel']">
    <xsl:value-of select="concat('-- ',@value)"/>
    <xsl:value-of select="$lf"/>
    <xsl:apply-templates select="child" mode="apparel"/>
</xsl:template>
<!-- match the child elements of apparel -->
<xsl:template match="child" mode="apparel">
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="concat('- ',./@value)"/>
    <xsl:value-of select="$lf"/>
</xsl:template>

<!-- match the accessories -->
<xsl:template match="child[@value='Accessories']">
    <xsl:value-of select="concat('-- ',@value)"/>
    <xsl:value-of select="$lf"/>
    <xsl:apply-templates select="child" mode="accessories"/>
</xsl:template>
<!-- match the child elements of accessories -->
<xsl:template match="child" mode="accessories">
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="concat('- ',./@value)"/>
    <xsl:value-of select="$lf"/>
</xsl:template>



</xsl:stylesheet>

到这个XML输入:

<?xml version="1.0" encoding="ISO-8859-1"?>
<childrens>
<child id="1" value="Root Catalog" parent_id="0">
    <child id="2" value="Apparel" parent_id="1">
        <child id="4" value="Shirts" parent_id="2"/>
        <child id="5" value="Pants" parent_id="2"/>
    </child>
    <child id="3" value="Accessories" parent_id="1">
        <child id="6" value="Handbags" parent_id="3"/>
        <child id="7" value="Jewelry" parent_id="3"/>
    </child>
</child>
</childrens>

你得到这个输出:

Root Category

    -- Apparel
        - Shirts
        - Pants

    -- Accessories
        - Handbags
        - Jewelry

祝你好运, 彼得