[英]Nested xsl templates to extract complex element paths from XML
我正在使用一個名為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”的頂部節點,其子節點為“ AA”,“ AB”和“ AC”。 “ AA”有一個孩子“ AAA”,以此類推。
另外,可以在任意2個節點之間添加鏈接。 這些鏈接由元素定義。 在上面的示例中,我定義了“ ABB”和“ AC”之間的鏈接…鏈接從“ ABB”開始,因為它位於該節點的xml中,並且鏈接以“ AC”結束,該鏈接由箭頭鏈接的DESTINATION屬性編碼等於目標節點的ID。 圖片
請注意,其中一個節點的子類型為attribute,名稱為NAME =“ Callout”。 我正在使用這些“標注”節點來表示同義詞。 因此,默認概念“ AB”的同義詞為“ 1 2”。
我正在嘗試使用xml轉換來生成ElasticSearch的體裁擴展同義詞列表( https://www.elastic.co/guide/en/elasticsearch/guide/2.x/synonyms-expand-or-contract.html#synonyms -類型 )。 所以我想要以下……
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
其中大多數只是節點的路徑,我可以正常工作。 但是箭頭鏈接節點和標注節點讓我煩惱。 這是我到目前為止所擁有的……
<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循環中,如何確定是否存在箭頭鏈接,以及是否存在,找到目標節點,然后設置另一個節點,以繼續從該箭頭鏈接的目標鏈向上進行?
通常,要遵循交叉引用,您可以定義一個鍵,例如<xsl:key name="id" match="node" use="@ID"/>
,然后您可以在模板內部或每個帶有node
for元素作為上下文節點,請使用key('id', arrowlink/@DESTINATION)
查找/選擇所有引用的目標節點。
我使用了馬丁的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>
這是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,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.