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