Php 将多维数组转换为XML,然后使用递归XSLT函数

Php 将多维数组转换为XML,然后使用递归XSLT函数,php,xml,xslt,Php,Xml,Xslt,我在PHP中有一个函数,可以从给定路径检索所有目录和文件。这将返回一个数组,如下所示: array( "dirname1" => array( "dirname2" => array( "dirname3" => array( "0" => "file1", "1" => "file2", "2" => "file3"

我在PHP中有一个函数,可以从给定路径检索所有目录和文件。这将返回一个数组,如下所示:

array(
    "dirname1" => array(
        "dirname2" => array(
            "dirname3" => array(
                "0" => "file1",
                "1" => "file2",
                "2" => "file3"
            ),
            "0" => "file4",
            "1" => "file5",
            "2" => "file6",
            "dirname4" => array(
                "0" => "file7",
                "1" => "file8"
            )
        ),
        "0" => "file9",
        "1" => "file10"
    ),
    "0" => "file11",
    "1" => "file12",
    "2" => "file13"
);
我最后需要的是一个多维(不知道是否是确切的单词)列表,其中包含使用XSLT 1.0从XML文件生成的
  • ,如:

    <ul>
        <li class="dirname">
            dirname1
            <ul>
                <li class="dirname">
                    Dirname2
                    <ul>
                        <li class="dirname">
                            Dirname3
                            <ul>
                                <li>file1</li>
                                <li>file2</li>
                                <li>file3</li>
                            </ul>
                        </li>
                        <li>file4</li>
                        <li>file5</li>
                        <li>file6</li>
                        <li class="dirname">
                            dirname4
                            <ul>
                                <li>file7</li>
                                <li>file8</li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li>file9</li>
                <li>file10</li>
            </ul>
        </li>
        <li>file11</li>
        <li>file12</li>
        <li>file13</li>
    </ul>
    
    • dirname1
      • Dirname2
        • Dirname3
          • 文件1
          • 文件2
          • 文件3
        • 文件4
        • 文件5
        • 文件6
        • dirname4
          • 文件7
          • 文件8
      • 文件9
      • 文件10
    • 文件11
    • 文件12
    • 文件13
    最后,在每个
  • 中,我需要
    中的路径
    
  • 实际上,我没有需要转换的XML,因为我不知道什么是一个好的结构,然后将其转换为XSLT1.0。我在
    中有路径。如果需要的话,我可以用PHP实现,我可以在PHP中检测它是目录还是非目录,我们还可以在XML上添加一些东西来检测
    class=“dirname”

    我希望我已经提供了足够的信息来理解我


    提前谢谢你

    PHP部分

    function ulRenderer($dirs, $path = array()) {
        echo '<ul>';
        foreach ($dirs as $key => $value) {
            if (is_array($value)) {
                printf(
                    '<li class="dirname"><a href="%s">%s</a>',
                    implode('/', $path),
                    $key
                );
    
                ulRenderer($value, array_merge(
                    $path, array($key)
                ));
                echo '</li>';
            }
            else {
                printf(
                    '<li><a href="%s/%s">%s</a></li>',
                    implode('/', $path),
                    $value, $value
                );
            }
        }
        echo '</ul>';
    }
    
    $dirs = array(
        "dirname1" => array(
            "dirname2" => array(
                "dirname3" => array(
                    "0" => "file1",
                    "1" => "file2",
                    "2" => "file3"
                ),
                "0" => "file4",
                "1" => "file5",
                "2" => "file6",
                "dirname4" => array(
                    "0" => "file7",
                    "1" => "file8"
                )
            ),
            "0" => "file9",
            "1" => "file10"
        ),
        "0" => "file11",
        "1" => "file12",
        "2" => "file13"
    );
    
    
    ulRenderer($dirs);
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="dir">
            <ul>
                <li>
                    <a>
                        <xsl:attribute name="href">
                            <xsl:call-template name="path" />
                        </xsl:attribute>
                        <xsl:value-of select="@name" />
                    </a>
                    <xsl:apply-templates />
                </li>
            </ul>
        </xsl:template>
    
        <xsl:template match="file">
            <li>
                <a>
                    <xsl:attribute name="href">
                        <xsl:call-template name="path" />
                    </xsl:attribute>
                    <xsl:value-of select="." />
                </a>
            </li>
        </xsl:template>
    
        <xsl:template name="path">
            <xsl:if test="parent::dir">
                <xsl:for-each select="ancestor::dir">
                    <xsl:sort select="position()" order="ascending"/>
                    <xsl:value-of select="@name" />
                    <xsl:text>/</xsl:text>
                </xsl:for-each>
            </xsl:if>
            <xsl:choose>
                <xsl:when test="name() = 'dir'">
                    <xsl:value-of select="@name" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="." />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
    </xsl:stylesheet>
    
    隧道参数:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:strip-space elements="*"/>
        <xsl:template match="node()|@*" name="identity">
            <xsl:param name="pPath"/>
            <xsl:copy>
                <xsl:apply-templates select="node()|@*">
                    <xsl:with-param name="pPath" select="$pPath"/>
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="li[@class='dirname']">
            <xsl:param name="pPath"/>
            <xsl:call-template name="identity">
                <xsl:with-param name="pPath"
                 select="concat($pPath,'/',normalize-space(text()[1]))"/>
            </xsl:call-template>
        </xsl:template>
        <xsl:template match="text()">
            <xsl:param name="pPath"/>
            <xsl:call-template name="text">
                <xsl:with-param name="pPath"
                 select="concat($pPath,'/',normalize-space())"/>
            </xsl:call-template>
        </xsl:template>
        <xsl:template match="li[@class='dirname']/text()" name="text">
            <xsl:param name="pPath"/>
            <a href="{$pPath}">
                <xsl:value-of select="."/>
            </a>
        </xsl:template>
    </xsl:stylesheet>
    
    
    
    输出:

    <ul>
        <li class="dirname">
            <a href="/dirname1">
                dirname1
            </a>
            <ul>
                <li class="dirname">
                    <a href="/dirname1/Dirname2">
                        Dirname2
                    </a>
                    <ul>
                        <li class="dirname">
                            <a href="/dirname1/Dirname2/Dirname3">
                                Dirname3
                            </a>
                            <ul>
                                <li>
                                    <a href="/dirname1/Dirname2/Dirname3/file1"
                                    >file1</a>
                                </li>
                                <li>
                                    <a href="/dirname1/Dirname2/Dirname3/file2"
                                    >file2</a>
                                </li>
                                <li>
                                    <a href="/dirname1/Dirname2/Dirname3/file3"
                                    >file3</a>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <a href="/dirname1/Dirname2/file4">file4</a>
                        </li>
                        <li>
                            <a href="/dirname1/Dirname2/file5">file5</a>
                        </li>
                        <li>
                            <a href="/dirname1/Dirname2/file6">file6</a>
                        </li>
                        <li class="dirname">
                            <a href="/dirname1/Dirname2/dirname4">
                                dirname4
                            </a>
                            <ul>
                                <li>
                                    <a href="/dirname1/Dirname2/dirname4/file7"
                                    >file7</a>
                                </li>
                                <li>
                                    <a href="/dirname1/Dirname2/dirname4/file8"
                                    >file8</a>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li>
                    <a href="/dirname1/file9">file9</a>
                </li>
                <li>
                    <a href="/dirname1/file10">file10</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="/file11">file11</a>
        </li>
        <li>
            <a href="/file12">file12</a>
        </li>
        <li>
            <a href="/file13">file13</a>
        </li>
    </ul>
    

    可能重复@Gordon:我还需要XSLT中的递归函数,这不是他们在链接中要求的。无论如何,谢谢你。:)@戈登:对不起,英语不是我的主要语言。ul/li输出列表需要从XML文件生成。我补充了这一点:我最终需要的是一个多维(不知道是否是确切的单词)列表,其中包含使用XSLT1.0从XML生成的
    • file@udexter为什么要用XSLT来实现呢?为什么不能从多维php数组中创建html输出?@udexter:为什么不在标题中使用递归替换多维?这可能更好理解?这只是个主意?谢谢!它在生成XML结构时会很有帮助。现在看看是否有人能帮我处理XSLT部分@亚历杭德罗:谢谢你的XSLT。您的XML输入是什么样的?提前谢谢你!我尝试过这个输入,但没有得到相同的输出:@udexter:我正在使用您发布的输入。你链接的这个新的@class没有任何@class等于
      “dirname”
      @Alejandro:啊!这是最终需要的输出,也是我在HTML中需要的。我不知道用XML处理它以获得最终的HTML是什么好的结构。你建议使用更好的XML吗?@udexter:任何模式都可以工作,只要它拥有所有信息。。。我们都在用你贴的那个。如果这不是正确的,请更新。
      $dom = new DOMDocument;
      $dom->load('dirs.xml');
      
      $xsl = new DOMDocument;
      $xsl->load('dirs.xslt', LIBXML_NOCDATA);
      
      $xslt = new XSLTProcessor();
      $xslt->importStylesheet($xsl);
      
      echo $xslt->transformToXML($dom);
      
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:strip-space elements="*"/>
          <xsl:template match="node()|@*" name="identity">
              <xsl:param name="pPath"/>
              <xsl:copy>
                  <xsl:apply-templates select="node()|@*">
                      <xsl:with-param name="pPath" select="$pPath"/>
                  </xsl:apply-templates>
              </xsl:copy>
          </xsl:template>
          <xsl:template match="li[@class='dirname']">
              <xsl:param name="pPath"/>
              <xsl:call-template name="identity">
                  <xsl:with-param name="pPath"
                   select="concat($pPath,'/',normalize-space(text()[1]))"/>
              </xsl:call-template>
          </xsl:template>
          <xsl:template match="text()">
              <xsl:param name="pPath"/>
              <xsl:call-template name="text">
                  <xsl:with-param name="pPath"
                   select="concat($pPath,'/',normalize-space())"/>
              </xsl:call-template>
          </xsl:template>
          <xsl:template match="li[@class='dirname']/text()" name="text">
              <xsl:param name="pPath"/>
              <a href="{$pPath}">
                  <xsl:value-of select="."/>
              </a>
          </xsl:template>
      </xsl:stylesheet>
      
      <ul>
          <li class="dirname">
              <a href="/dirname1">
                  dirname1
              </a>
              <ul>
                  <li class="dirname">
                      <a href="/dirname1/Dirname2">
                          Dirname2
                      </a>
                      <ul>
                          <li class="dirname">
                              <a href="/dirname1/Dirname2/Dirname3">
                                  Dirname3
                              </a>
                              <ul>
                                  <li>
                                      <a href="/dirname1/Dirname2/Dirname3/file1"
                                      >file1</a>
                                  </li>
                                  <li>
                                      <a href="/dirname1/Dirname2/Dirname3/file2"
                                      >file2</a>
                                  </li>
                                  <li>
                                      <a href="/dirname1/Dirname2/Dirname3/file3"
                                      >file3</a>
                                  </li>
                              </ul>
                          </li>
                          <li>
                              <a href="/dirname1/Dirname2/file4">file4</a>
                          </li>
                          <li>
                              <a href="/dirname1/Dirname2/file5">file5</a>
                          </li>
                          <li>
                              <a href="/dirname1/Dirname2/file6">file6</a>
                          </li>
                          <li class="dirname">
                              <a href="/dirname1/Dirname2/dirname4">
                                  dirname4
                              </a>
                              <ul>
                                  <li>
                                      <a href="/dirname1/Dirname2/dirname4/file7"
                                      >file7</a>
                                  </li>
                                  <li>
                                      <a href="/dirname1/Dirname2/dirname4/file8"
                                      >file8</a>
                                  </li>
                              </ul>
                          </li>
                      </ul>
                  </li>
                  <li>
                      <a href="/dirname1/file9">file9</a>
                  </li>
                  <li>
                      <a href="/dirname1/file10">file10</a>
                  </li>
              </ul>
          </li>
          <li>
              <a href="/file11">file11</a>
          </li>
          <li>
              <a href="/file12">file12</a>
          </li>
          <li>
              <a href="/file13">file13</a>
          </li>
      </ul>