XSL:使用标记化生成.dot有向图连接列表?

时间:2018-09-28 14:57:06

标签: xml xslt

大多数情况下,我是XSL新手。只是事先说。 :)

我正在尝试转换看起来像这样的XML:

<?xml-stylesheet type="text/xsl" href="simple.xsl"?>
<root>
    <node>
        <name>A</name>
        <out>D, B, C, </out>
    </node>

    <node>
        <name>B</name>
        <out>A, E, C, </out>
    </node>

</root>

进入一个如下所示的.dot文件:

Digraph G
{
    A -> D 
    A -> B 
    A -> C 
    B -> A
    B -> E
    B -> C
}

使用XSL。到目前为止,我对XSL的了解,

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:strip-space elements="*" />

<xsl:template match="/">
Digraph G
{
    <xsl:apply-templates select="root/node/out"/>
}
</xsl:template>

<xsl:template match="root/node/out">
 <xsl:call-template name="tokenize"> 
   <xsl:with-param name="csv" select="." /> 
 </xsl:call-template>    
</xsl:template>

<xsl:template name="tokenize">
 <xsl:param name="csv" />
  <xsl:variable name="iter" select="normalize-space( 
    substring-before( concat( $csv, ','), ','))" /> 
 <xsl:if test="$iter">
 <!-- X is a placeholder -->
  X -> <xsl:value-of select="$iter" /> 

  <xsl:call-template name="tokenize"> 
   <xsl:with-param name="csv" select="substring-after($csv,',')" /> 
  </xsl:call-template>    
 </xsl:if>  
</xsl:template>

</xsl:stylesheet>

在这里得到此输出:

Digraph G
{

  X -> D
  X -> B
  X -> C
  X -> A
  X -> E
  X -> C
}

我不会说谎:我发现了XSL代码的一部分,做了一些研究,并弄清楚了一些有效的方法。我至少让终端节点工作正常;我现在的问题是获取初始节点。

我的想法是我必须以某种方式做一个嵌套的for-each循环,将属性作为参数传递。

伪代码提示:

For each <node/name>
    Parameter n = <name>

    For-each <node/out> of n
        <name> -> <out>

我仍在尝试掌握XSL背后的逻辑,因此,我试图弄清楚如何将令牌化集成到此问题中。对我来说还不是很明显。我一直在努力寻求解决方案,但是还没有点击em。

非常感谢您的帮助。随时谢谢你 -乔恩

1 个答案:

答案 0 :(得分:0)

更改

<xsl:template match="root/node/out">
 <xsl:call-template name="tokenize"> 
   <xsl:with-param name="csv" select="." /> 
 </xsl:call-template>    
</xsl:template>

<xsl:template match="root/node/out">
 <xsl:call-template name="tokenize"> 
   <xsl:with-param name="csv" select="." /> 
   <xsl:with-param name="name" select="../name"/>
 </xsl:call-template>    
</xsl:template>

然后确保您在命名模板中声明该参数,并将其与例如<xsl:value-of select="$name"/>的输出位置,当然还要确保使用call-template在递归<xsl:with-param name="name" select="$name"/>中将其传递。

作为XSLT的新手,我建议您研究当前版本的XSLT 3或11年的XSLT 2(其中tokenize可作为XPath函数使用),而不是为20年的历史而争执。 XSLT 1和递归可调用模板。