带递归的 XSLT 转换

问题描述 投票:0回答:3

我需要将 XML 文档转换为 HTML。

输入XML:

<items>
    <item no="1" par_no="0" user="Mike">Hi all!</item>
    <item no="2" par_no="1" user="Jane">Hi...</item>
    <item no="3" par_no="2" user="Pit"> says: wasap man?</item>
    <item no="4" par_no="2" user="Karol">are you ok?</item>
    <item no="5" par_no="4" user="Nick">I think he's not in the mood.</item>
    <item no="6" par_no="5" user="Karol">I just ask a question.</item>
    <item no="7" par_no="1" user="Pit">says: how are you?</item>
    <item no="8" par_no="7" user="Mike">fine!</item>
</items>

输出 HTML:

<?xml version="1.0" encoding="UTF-8"?>
<ul>
  <li><b>Mike</b> says: Hi all!
    <ul>
      <li><b>Jane</b>  says: Hi...
          <li><b>Pit</b> says: wasap man?
          <li><b>Karol</b> says: are you ok?
            <ul>
              <li><b>Nick</b> says: I tihnk he's not in the mood.
                <ul>
                  <li><b>Karol</b> says: I just ask a question.
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li><b>Pit</b> says: how are you?
        <ul>
          <li><b>Mike</b> says: fine!
        </ul>
      </li>
    </ul>
  </li>
</ul>

我试图解决这个问题。我得到了代码。正在对行进行排序,但我无法获取附件。我的 XSL:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
 <xsl:output method="html" /> 
 <xsl:template match="items"> 
    <html> 
        <ul>
            <xsl:apply-templates select="item[@par_no=0]"/> 
            
        </ul>
    </html> 
 </xsl:template> 
 
 <xsl:template match="item">    
    
    <xsl:variable name="varNo" select="@no"/> 
    
        <li>
            <b><xsl:value-of select="@user"/></b>
            <xsl:text> says: </xsl:text>
            <xsl:value-of select="."/> 
        </li>   
 
    <xsl:apply-templates select="//items/item[@par_no=$varNo]"> 
        <xsl:sort select="@par_no" data-type="number"/>                 
    </xsl:apply-templates> 
    
 </xsl:template> 
</xsl:stylesheet>

我不知道在哪里插入标签才能得到这样的嵌套结构。请帮忙!

xml recursion xslt
3个回答
0
投票

在 XSLT 3 中,您可以按如下方式解决:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">
  
  <xsl:output method="html" version="5.0" indent="yes"/>
  
  <xsl:template match="/">
    <html>
      <head>
        <title>Test</title>
      </head>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  
  <xsl:key name="child" match="item" use="@par_no"/>

  <xsl:template match="items">
    <ul>
      <xsl:apply-templates select="key('child', '0')"/>
    </ul>
  </xsl:template>
  
  <xsl:template match="item">
    <li>
        <b><xsl:value-of select="@user"/></b>
        <xsl:text> says: </xsl:text>
        <xsl:value-of select="."/> 
        <xsl:where-populated>
          <ul>
            <xsl:apply-templates select="key('child', @no)"/>
          </ul>
        </xsl:where-populated>
    </li>
  </xsl:template>
  
</xsl:stylesheet>

密钥和模板在以前的版本中的工作方式相同,您需要将

xsl:where-populated
替换为检查
key('child', @no)
是否选择元素以输出
ul

  <xsl:template match="item">
    <li>
        <b><xsl:value-of select="@user"/></b>
        <xsl:text> says: </xsl:text>
        <xsl:value-of select="."/> 
        <xsl:variable name="children" select="key('child', @no)"/>
        <xsl:if test="$children">
          <ul>
            <xsl:apply-templates select="$children"/>
          </ul>
        </xsl:if>
    </li>
  </xsl:template>

0
投票

我认为你可以简单地做(仅使用 XSLT 1.0):

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

<xsl:key name="chld" match="item" use="@par_no" />

<xsl:template match="/items">
    <ul>
        <xsl:apply-templates select="item[@par_no='0']"/>
    </ul>
</xsl:template>

<xsl:template match="item">
    <li>
        <b>
            <xsl:value-of select="@user"/>
        </b>
        <xsl:text> says: </xsl:text>
        <xsl:value-of select="."/>
        <ul>
            <xsl:apply-templates select="key('chld', @no)"/>
        </ul>
    </li>
</xsl:template>

</xsl:stylesheet>

浏览器中显示的结果是:


0
投票

是的,我致力于 XSLT 1.0。但我没有得到这个结果。在我的 Chrome 浏览器中,结果有所不同。不幸的是我无法发布图片(( 我需要像你的照片一样的结果! HTML:

<ul>
  <li><b>Mike</b> says: Hi all!
    <ul>
      <li> <b>Jane</b> says: Hi...
        <ul>
          <li><b>Pit</b> says: asap man?</li>
          <li><b>Karol</b> says: are you ok?
            <ul>
              <li><b>Nick</b> says: I think he's not in the mood.
                <ul>
                  <li><b>Karol</b> says: I just ask a question.</li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li><b>Pit</b> says: how are you?
        <ul>
          <li><b>Mike</b> says: fine!</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

为什么说 Pit 会重复两次?

© www.soinside.com 2019 - 2024. All rights reserved.