我有一个像XML结构的文件系统,现在我想得到一个“文件路径”。我尝试了以下XSLT,但它不起作用。我只得到这些错误:
警告: XSLTProcessor中:: transformToXml(): 模板:in C:\ Users \用户卢德格尔\文件\ XAMPP \ htdocs中\ CloudAmp \ devel的\ PHP \ localAudioFileLocationScanner.php 在第60行
警告: XSLTProcessor :: transformToXml():#0 名称//文件 C:\ Users \用户卢德格尔\文件\ XAMPP \ htdocs中\ CloudAmp \ devel的\ PHP \ localAudioFileLocationScanner.php 在第60行
警告: XSLTProcessor :: transformToXml():#1 名称//文件 第60行的C:\ Users \ Ludger \ Documents \ XAMPP \ htdocs \ CloudAmp \ devel \ php \ localAudioFileLocationScanner.php
[...]
警告:XSLTProcessor :: transformToXml(): xsltApplyXSLTTemplate:潜力 无限模板递归 检测。您可以调整xsltMaxDepth (--maxdepth)为了提高 嵌套模板的最大数量 调用和变量/参数(目前 设为3000)。在 C:\ Users \用户卢德格尔\ DocumentsXA MPP \ htdocs中\ CloudAmp \ devel的\ PHP \ localAudioFileLocationScanner.php 在第60行
XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/dir">
<xsl:apply-templates select="@name" />
<xsl:apply-templates select="parent::dir" />
</xsl:template>
<xsl:template match="//file">
<xsl:apply-templates select="@name" />
<xsl:apply-templates select="parent::dir" />
</xsl:template>
</xsl:stylesheet>
源XML:
<root>
<path val="C:/Users/">
<file name="a.txt"/>
<dir name="aaa">
<file name="b.txt"/>
<file name="c.txt"/>
</dir>
<dir name="bbb">
<dir name="ccc">
<file name="d.txt"/>
</dir>
</dir>
</path>
</root>
我无法让它发挥作用。如果你可以帮助我,那就太棒了。
答案 0 :(得分:1)
正在发生的事情是,您匹配任何file
元素,然后将模板应用于其父dir
,后者与元素的默认模板匹配,后者将模板应用于其所有子元素,导致另一个匹配file
并开始无限递归。
(请注意,dir
元素的模板永远不会匹配任何内容,因为它只查找作为根节点子节点的dir
元素,但是没有。{ / em>的
以下样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="dir" mode="path">
<xsl:value-of select="@name" />
<xsl:text>/</xsl:text>
</xsl:template>
<xsl:template match="file">
<xsl:apply-templates select="ancestor::dir" mode="path"/>
<xsl:value-of select="@name" />
</xsl:template>
</xsl:stylesheet>
产生以下输出:
a.txt
aaa/b.txt
aaa/c.txt
bbb/ccc/d.txt
编辑:我认为,当可以避免回溯时,推进文档通常会更好。以下样式表生成与上面相同的输出,但更高效和更优雅:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="dir">
<xsl:param name="prev" select="''" />
<xsl:apply-templates>
<xsl:with-param name="prev" select="concat($prev, @name, '/')" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="file">
<xsl:param name="prev" select="''" />
<xsl:value-of select="concat($prev, @name)" />
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
此转化:
<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="file">
<xsl:apply-templates mode="buildPath"
select="ancestor::*[not(self::root or self::path)]"/>
<xsl:value-of select="concat(@name, '
')"/>
</xsl:template>
<xsl:template match="*" mode="buildPath">
<xsl:value-of select="concat(@name,'/')"/>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<root>
<path val="C:/Users/">
<file name="a.txt"/>
<dir name="aaa">
<file name="b.txt"/>
<file name="c.txt"/>
</dir>
<dir name="bbb">
<dir name="ccc">
<file name="d.txt"/>
</dir>
</dir>
</path>
</root>
会产生想要的正确结果:
a.txt
aaa/b.txt
aaa/c.txt
bbb/ccc/d.txt