Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xslt将xhtml转换为wiki语法_Xslt_Xhtml_Syntax_Wiki - Fatal编程技术网

使用xslt将xhtml转换为wiki语法

使用xslt将xhtml转换为wiki语法,xslt,xhtml,syntax,wiki,Xslt,Xhtml,Syntax,Wiki,我想使用xslt将xhtml转换为dokuwiki语法 现在,有一件事我似乎无法解决,那就是如何处理嵌套列表。dokuwiki语法对列表项使用星号(*),每个嵌套级别(c.f.)前面有两个空格 我的问题:在下面的示例中,与列表项目2.1.1匹配的如何知道它的嵌套级别,以便预先准备适当数量的空白 * list item 1 * list item 2 * list item 2.1 * list item 2.1.1 * list item 2.2 * list item 2.

我想使用xslt将xhtml转换为dokuwiki语法

现在,有一件事我似乎无法解决,那就是如何处理嵌套列表。dokuwiki语法对列表项使用星号(*),每个嵌套级别(c.f.)前面有两个空格

我的问题:在下面的示例中,与列表项目2.1.1匹配的如何知道它的嵌套级别,以便预先准备适当数量的空白

* list item 1
* list item 2
  * list item 2.1
    * list item 2.1.1
  * list item 2.2
  * list item 2.3
* list item 3
对应于

  • 清单项目1
  • 清单项目2
    • 清单项目2.1
      • 清单项目2.1.1
    • 清单项目2.2
    • 清单项目2.3
  • 清单项目3
以下html是如何显示的:

<ul>
    <li>
        list item 1
    </li>
    <li>
        list item 2
        <ul>
            <li>
                list item 2.1
                <ul>
                    <li>list item 2.1.1</li>
                </ul>
            </li>
            <li>list item 2.2</li>
            <li>list item 2.3</li>
        </ul>
    </li>
    <li>
        list item 3
    </li>
</ul>
  • 清单项目1
  • 清单项目2
    • 清单项目2.1
      • 清单项目2.1.1
    • 清单项目2.2
    • 清单项目2.3
  • 清单项目3

以下是我如何让它工作的:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="//li">
        <xsl:call-template name="loop">
            <xsl:with-param name="maxcount" select="count(ancestor::li)"/>
            <xsl:with-param name="initial-value" select="0"/>
        </xsl:call-template>
        <xsl:text>* </xsl:text>
        <xsl:value-of select="normalize-space(text())"/>
        <xsl:text>&#xd;</xsl:text>
        <xsl:apply-templates select="ul/li" />
    </xsl:template>
    <xsl:template name="loop">
        <xsl:param name="maxcount"/>
        <xsl:param name="initial-value"/>
        <xsl:if test="$initial-value &lt; $maxcount">
            <xsl:text>&#x9;</xsl:text>
            <xsl:call-template name="loop">
                <xsl:with-param name="maxcount" select="$maxcount"/>
                <xsl:with-param name="initial-value" select="$initial-value+1"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
该块只输出前面有
*
的文本,后面有一个换行符(
)。请注意,我使用了
text()
函数而不是
来检索节点的值。如果不这样做,则父节点的输出将(根据W3C建议应该这样做)将所有子文本节点与父节点连接起来

<xsl:apply-templates select="ul/li" />


最后,我们递归调用当前模板,但显式引用下一个
  • ,该模板是
    的直接子级-这可以防止我们在同一父元素上意外调用模板两次。

    以下转换

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
    
     <xsl:strip-space elements="*"/>
    
     <xsl:variable name="vBlanks"
      select="'                                        '"/>
     <xsl:variable name="vnNestSpaces" select="2"/>
    
    
        <xsl:template match="li">
          <xsl:variable name="vNestLevel"
               select="count(ancestor::li)"/>
          <xsl:value-of select=
           "concat('&#xA;',
                   substring($vBlanks,1,$vnNestSpaces*$vNestLevel),
                   '*  ', normalize-space(text()[1])
                   )"/>
          <xsl:apply-templates select="*"/>
        </xsl:template>
    </xsl:stylesheet>
    
    <ul>
        <li> list item 1
        </li>
        <li> list item 2        
            <ul>
                <li> list item 2.1                
                    <ul>
                        <li>list item 2.1.1</li>
                    </ul>
                </li>
                <li>list item 2.2</li>
                <li>list item 2.3</li>
            </ul>
        </li>
        <li> list item 3    </li>
    </ul>
    
    *  list item 1
    *  list item 2
      *  list item 2.1
        *  list item 2.1.1
      *  list item 2.2
      *  list item 2.3
    *  list item 3
    
    注意以下事项:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
    
     <xsl:strip-space elements="*"/>
    
     <xsl:variable name="vBlanks"
      select="'                                        '"/>
     <xsl:variable name="vnNestSpaces" select="2"/>
    
    
        <xsl:template match="li">
          <xsl:variable name="vNestLevel"
               select="count(ancestor::li)"/>
          <xsl:value-of select=
           "concat('&#xA;',
                   substring($vBlanks,1,$vnNestSpaces*$vNestLevel),
                   '*  ', normalize-space(text()[1])
                   )"/>
          <xsl:apply-templates select="*"/>
        </xsl:template>
    </xsl:stylesheet>
    
    <ul>
        <li> list item 1
        </li>
        <li> list item 2        
            <ul>
                <li> list item 2.1                
                    <ul>
                        <li>list item 2.1.1</li>
                    </ul>
                </li>
                <li>list item 2.2</li>
                <li>list item 2.3</li>
            </ul>
        </li>
        <li> list item 3    </li>
    </ul>
    
    *  list item 1
    *  list item 2
      *  list item 2.1
        *  list item 2.1.1
      *  list item 2.2
      *  list item 2.3
    *  list item 3
    
  • 所需的缩进由
    计数(ancesstor::li)
    的值确定

  • 缩进空间直接取自足够大的空行(包含足够20级嵌套的空行)。无需逐个递归输出空格

  • 转换效率更高,原因是2。上面

  • 注意XPath函数的使用


  • +1非常好!!我喜欢空白的想法——我知道必须有一个更好的方法来获得缩进。