这是不难XSLT 1.0做的,看我2004年的回答更具体的图遍历问题:
http://lists.xml.org/archives/xml-dev/200401/msg00444.html
下面是一个完整的XSLT 1.0有向图遍历解决方案,假设向链路特定的XML表示(如你忘了展现给我们的源XML文档......):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kNodeById" match="*" use="@id"/>
<xsl:template match="/">
<xsl:call-template name="gTraverse">
<xsl:with-param name="pNode" select="/*/a"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="gTraverse">
<xsl:param name="pNode"/>
<xsl:param name="pVisited" select="/.."/>
<xsl:param name="pMustVisit" select="/.."/>
<xsl:variable name="vnewVisited" select=
"$pVisited | $pNode"/>
<xsl:variable name="vnewNodes" select=
"key('kNodeById',
($pNode/linkTo
|
/*/*[linkTo=$pNode/@id])/@id
)
[not(@id = $vnewVisited/@id)]
"/>
<xsl:variable name="vnewMustVisit" select=
"$pMustVisit[count(.|$pNode) > 1] | $vnewNodes"/>
<xsl:choose>
<xsl:when test="not($vnewMustVisit)">
<xsl:copy-of select="$vnewVisited"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="gTraverse">
<xsl:with-param name="pNode" select=
"$vnewMustVisit[1]"/>
<xsl:with-param name="pVisited" select="$vnewVisited"/>
<xsl:with-param name="pMustVisit" select=
"$vnewMustVisit[position() > 1]"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当施加于下面的XML文档这种转变,表示有5个顶点向图:
<graph>
<a id ="1">
<linkTo>2</linkTo>
<linkTo>5</linkTo>
</a>
<b id ="2">
<linkTo>3</linkTo>
<linkTo>5</linkTo>
</b>
<c id ="3">
<linkTo>1</linkTo>
<linkTo>4</linkTo>
</c>
<d id ="4">
<linkTo>1</linkTo>
</d>
<e id ="5">
<linkTo>3</linkTo>
<linkTo>4</linkTo>
</e>
<f id ="6">
<linkTo>1</linkTo>
</f>
</graph>
正确的结果(曲线图的所有节点),产生:
<a id="1">
<linkTo>2</linkTo>
<linkTo>5</linkTo>
</a>
<b id="2">
<linkTo>3</linkTo>
<linkTo>5</linkTo>
</b>
<c id="3">
<linkTo>1</linkTo>
<linkTo>4</linkTo>
</c>
<d id="4">
<linkTo>1</linkTo>
</d>
<e id="5">
<linkTo>3</linkTo>
<linkTo>4</linkTo>
</e>
<f id="6">
<linkTo>1</linkTo>
</f>
你可以更具体地了解你的输入看起来如何?为什么不能将已遍历的元素存储在参数中,如http://lists.xml.org/archives/xml-dev/201110/msg00030.html中所做的那样? –
XSLT是一种声明性语言,而不是程序性语言。因此没有“早期”或“已经”或其他时间相关概念的概念。你需要重新思考这个过程的功能性。 –
样本输入,所需的输出以及样式表的尝试都会让您更容易地向您展示适用于您的情况的解决方案。 – LarsH