我正在使用名为iThoughts的思维导图应用程序来构建术语/本体。该应用程序使用可以通过边连接子项的文本节点。 iThoughts可以输出到xml。略微清理的版本看起来像这样......
<node ID="0659C319-781F-425B-B5C4-A58D9703058E" TEXT="A" STYLE="bubble" FOLDED="false" CREATED="1506338610407" MODIFIED="1506338655247">
<node ID="2FFA8D7E-31FC-4BDD-9237-03306E000E69" TEXT="A A" STYLE="bubble" FOLDED="false" POSITION="right" CREATED="1506338626015" MODIFIED="1506451463949">
<node ID="8CDBBE54-01FD-43E2-9E8C-FCEF05C939D0" TEXT="A A A" STYLE="bubble" FOLDED="false" CREATED="1506338633301" MODIFIED="1506451469473">
</node>
</node>
<node ID="F90EDE7F-1D1E-416E-B06D-C3DB272908C0" TEXT="A B" STYLE="bubble" FOLDED="false" POSITION="right" CREATED="1506338639646" MODIFIED="1506451486753">
<node ID="AEED653C-6EB9-4B04-8E74-B054EE2DFC4B" TEXT="A B A" STYLE="bubble" FOLDED="false" CREATED="1506338687585" MODIFIED="1506451473365">
</node>
<node ID="DD8AAAEF-EEB7-4DA0-AE69-DABB68617AB6" TEXT="A B B" STYLE="bubble" FOLDED="false" CREATED="1506338694145" MODIFIED="1506451477067">
<arrowlink DESTINATION="6377D5CA-5E48-42C1-8ECB-8B15D7E0DC65" COLOR="#FFB2B2" STARTARROW="None" ENDARROW="Default" SOURCE_LABEL="" MIDDLE_LABEL="" TARGET_LABEL=""/>
<node ID="B31AD99B-40D1-4A72-8EB6-8EBBD7100F28" TEXT="A B B A" STYLE="bubble" FOLDED="false" CREATED="1506451516240" MODIFIED="1506451522888">
</node>
</node>
<node ID="45D5FBFB-2FF2-4220-A0EB-6623891404AB" TEXT="1 2" STYLE="bubble" FOLDED="false" CREATED="1506451492888" MODIFIED="1506451497507">
<attribute NAME="Callout" VALUE="{-151, 114}"/>
</node>
</node>
<node ID="6377D5CA-5E48-42C1-8ECB-8B15D7E0DC65" TEXT="A C" STYLE="bubble" FOLDED="false" POSITION="right" CREATED="1506339141624" MODIFIED="1506451488789">
</node>
</node>
...定义了一个叫做“A”的顶级节点,它有一个孩子“A A”,“A B”和“A C”。 “A A”有一个孩子“A A A”等。
此外,可以在任意2个节点之间添加链接。这些链接由元素定义。在上面的示例中,我定义了“ABB”和“AC”之间的链接...链接从“ABB”开始,因为它在该节点的xml内,链接以“AC”结束,“AC”由arrowlink的DESTINATION属性编码等于目标节点的ID。 Image
请注意,其中一个节点的子类型属性为NAME =“Callout”。我正在使用这些“标注”节点来表示同义词。因此,名为“A B”的默认概念具有名为“1 2”的同义词。
我正在尝试使用xml转换为ElasticSearch(https://www.elastic.co/guide/en/elasticsearch/guide/2.x/synonyms-expand-or-contract.html#synonyms-genres)生成流派扩展同义词列表。所以我想要以下......
A => A
A A => A_A, A
A A A => A_A_A, A_A, A
A B, 1 2 => A_B, A
A B A => A_B_A, A_B, A
A B B => A_B_B, A_B, A_C, A
A B B A => A_B_B_A, A_B_B, A_B, A_C, A
A C => A_C, A
这大部分只是节点的路径,我的工作正常。但是arrowlink节点和callout节点让我感到烦恼。这就是我到目前为止......
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()"/>
<xsl:template match="node[not (attribute)]">
<xsl:value-of select="concat(@TEXT, ' => ')"/>
<xsl:for-each select="ancestor-or-self::node[not (attribute)]">
<xsl:sort select="position()" data-type="number" order="descending"/>
<xsl:value-of select="concat(string-join( tokenize(@TEXT, '\s'), '_'), ', ')"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>
从for-each循环中,如何确定是否存在arrowlink,如果有,找到目标节点,然后用另一个设置另一个从该arrowlink的目标继续链接?
答案 0 :(得分:1)
通常,要遵循交叉引用,您可以定义一个键,例如<xsl:key name="id" match="node" use="@ID"/>
然后您可以在模板内部或for-each中使用node
元素作为上下文节点使用key('id', arrowlink/@DESTINATION)
来查找/选择所有引用的目标节点。
答案 1 :(得分:0)
我使用了马丁的key('id', arrowlink/@DESTINATION)
建议(谢谢)并想出了以下内容......
这是一个稍微复杂的xml,包含多个交叉引用,包括多级交叉引用。
<?xml version="1.0"?>
<map version="0.9.0">
<node ID="0659C319-781F-425B-B5C4-A58D9703058E" TEXT="A">
<node ID="2FFA8D7E-31FC-4BDD-9237-03306E000E69" TEXT="A A">
<node ID="8CDBBE54-01FD-43E2-9E8C-FCEF05C939D0" TEXT="A A A">
<arrowlink DESTINATION="1DC44430-AD4A-4EDF-938E-85DE5BC4CA5C" />
</node>
</node>
<node ID="F90EDE7F-1D1E-416E-B06D-C3DB272908C0" TEXT="A B" >
<node ID="AEED653C-6EB9-4B04-8E74-B054EE2DFC4B" TEXT="A B A" >
</node>
<node ID="DD8AAAEF-EEB7-4DA0-AE69-DABB68617AB6" TEXT="A B B" >
<node ID="B31AD99B-40D1-4A72-8EB6-8EBBD7100F28" TEXT="A B B A" >
<arrowlink DESTINATION="42ACB35A-1DA7-4C79-BA40-2D4636C9C7DE" />
</node>
</node>
</node>
<node ID="6377D5CA-5E48-42C1-8ECB-8B15D7E0DC65" TEXT="A C" >
<node ID="42ACB35A-1DA7-4C79-BA40-2D4636C9C7DE" TEXT="A C A" >
<arrowlink DESTINATION="1DC44430-AD4A-4EDF-938E-85DE5BC4CA5C" />
</node>
</node>
<node ID="1DC44430-AD4A-4EDF-938E-85DE5BC4CA5C" TEXT="A D" >
</node>
</node>
</map>
And here is what it looks like visually
这是xslt ......
<xsl:template match="/">
<xsl:apply-templates select="node()" mode="one"/>
</xsl:template>
<xsl:template match="node[not (attribute)]" mode="one">
<xsl:value-of select="concat(@TEXT, ' => ')"/>
<xsl:for-each select="ancestor-or-self::node[not (attribute)]">
<xsl:sort select="position()" data-type="number" order="descending"/>
<xsl:value-of select="concat(string-join( tokenize(@TEXT, '\s'), '_'), ', ')"/>
<xsl:if test="./arrowlink">
<xsl:apply-templates select="key('id', arrowlink/@DESTINATION)" mode="two"/>
</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="node()" mode="one"/>
</xsl:template>
<xsl:template match="node[not (attribute)]" mode="two">
<xsl:for-each select="ancestor-or-self::node[not (attribute)]">
<xsl:sort select="position()" data-type="number" order="descending"/>
<xsl:value-of select="concat(string-join( tokenize(@TEXT, '\s'), '_'), ', ')"/>
<xsl:if test="./arrowlink">
<xsl:apply-templates select="key('id', arrowlink/@DESTINATION)" mode="two"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这是输出......
A => A,
A A => A_A, A,
A A A => A_A_A, A_D, A, A_A, A,
A B => A_B, A,
A B A => A_B_A, A_B, A,
A B B => A_B_B, A_B, A,
A B B A => A_B_B_A, A_C_A, A_D, A, A_C, A, A_B_B, A_B, A,
A C => A_C, A,
A C A => A_C_A, A_D, A, A_C, A,
A D => A_D, A,