簡體   English   中英

嵌套的xsl模板,用於從XML中提取復雜的元素路徑

[英]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>&#xA;</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>&#xA;</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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM