2015-09-30 52 views
-3

在處理Xpath表達式時,我堅持一種情況,在這種情況下,我必須找出依賴於其他節點的一個元素的節點。如何使用XPath從XML中檢索遞歸元素

下面是使用的XML示例:

<?xml version="1.0" encoding="UTF-8" ?> 

<parent1> 
    <child1 id="1"> 
     <in>Starting1</in> 
     <out>connect1</out> 
    </child1> 
    <child1 id="2"> 
     <in>connect1</in> 
     <out>connect1.1</out> 
    </child1> 
    <child1 id="3"> 
     <in>Starting2</in> 
     <out>connect2</out> 
    </child1> 
    <child1 id="4"> 
     <in>connect1.1</in> 
     <out>connect1.2</out> 
    </child1> 
    <child1 id="5"> 
     <in>connect1.2</in> 
     <out>end1</out> 
    </child1> 
    <child1 id="6"> 
     <in>connect2</in> 
     <out>connect2.1</out> 
    </child1> 
    <child1 id="7"> 
     <in>connect2.1</in> 
     <out>connect2.2</out> 
    </child1> 
    <child1 id="8"> 
     <in>connect2.2</in> 
     <out>open2</out> 
    </child1> 
</parent1> 

希望的輸出是找出節點,其具有開始點作爲「啓動」,然後行進到另一個節點(裝置出來的節點是在對於其他節點)&不以「結束」結尾。

開始和結束之間可能有x個連接。

我已經使用了下面的xpath表達式。但是這僅限於2級遞歸。

//parent1/child1[in=(//parent1/child1[in=(//parent1/child1[in=(//parent1/child1[contains(in,"Starting")]/out)]/out)]/out) and not(contains(out,"end"))] 

輸出:

<child1 id="8"> 
    <in>connect2.2</in> 
    <out>open2</out> 
</child1> 

至於,我不知道如何連接器的數量很多可能是在節點之間。那麼,XML1.0中有沒有辦法找到遞歸?

有一個duplicate question already in stackoverflow.但是,我沒有從那裏得到解決方案。

enter image description here

+2

你的問題很難理解。輸入中沒有「開始」點,只有「開始1」和「開始2」。並且可能有多個節點符合標準。請用更清晰的語言說明您的要求。 –

+0

包含(in,「開始」)標記表示,標記文本包含「開始」字符串。你可以檢查xpath表達式 –

回答

1

您的要求不是很清楚。從小事我想我明白了,我相信你會做到這一點有兩種passes.Here的部分例如:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common" 
extension-element-prefixes="exsl"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="edge-by-in" match="child1" use="in" /> 
<xsl:key name="edge-by-out" match="child1" use="out" /> 

<xsl:template match="/parent1"> 
    <xsl:variable name="first-pass"> 
     <xsl:for-each select="child1"> 
      <edge id="{@id}"> 
       <xsl:apply-templates select="." mode="find-start"/> 
       <xsl:apply-templates select="." mode="find-end"/> 
      </edge> 
     </xsl:for-each> 
    </xsl:variable> 
    <output> 
     <!-- process the nodes contained in $first-pass --> 
    </output> 
</xsl:template> 

<xsl:template match="child1" mode="find-start"> 
    <xsl:variable name="prev" select="key('edge-by-out', in)" /> 
    <xsl:choose> 
     <xsl:when test="$prev"> 
      <xsl:apply-templates select="$prev" mode="find-start"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <start> 
       <xsl:value-of select="in"/> 
      </start> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="child1" mode="find-end"> 
    <xsl:variable name="next" select="key('edge-by-in', out)" /> 
    <xsl:choose> 
     <xsl:when test="$next"> 
      <xsl:apply-templates select="$next" mode="find-end"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <end> 
       <xsl:value-of select="out"/> 
      </end> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

</xsl:stylesheet> 

當您應用了此信息輸入時,$first-pass變量將包含:

<edge id="1"> 
     <start>Starting1</start> 
     <end>end1</end> 
    </edge> 
    <edge id="2"> 
     <start>Starting1</start> 
     <end>end1</end> 
    </edge> 
    <edge id="3"> 
     <start>Starting2</start> 
     <end>open2</end> 
    </edge> 
    <edge id="4"> 
     <start>Starting1</start> 
     <end>end1</end> 
    </edge> 
    <edge id="5"> 
     <start>Starting1</start> 
     <end>end1</end> 
    </edge> 
    <edge id="6"> 
     <start>Starting2</start> 
     <end>open2</end> 
    </edge> 
    <edge id="7"> 
     <start>Starting2</start> 
     <end>open2</end> 
    </edge> 
    <edge id="8"> 
     <start>Starting2</start> 
     <end>open2</end> 
    </edge> 

現在你可以用它來選擇具有節點(或沒有)特定startend

0

// parent1/child1 [含有(在/文本(), '正在啓動'),而不是(含有(OUT /文本(), '結束'))]

UPDATE

看看圖像。它返回你問什麼了:

enter image description here

所需的輸出是找出節點,這是有起點 爲「啓動」 &不在「結束」的結局。

你能更新你的問題嗎?也許用你期望使用XML添加的輸出。

+0

這將使我返回這兩個元素。因爲child1標籤不包含單個標籤中的開始和結束。它通過引用 –

+0

連接我的要求是找出最後一個連接節點。像來自child @ id = 1的元素是child @ id = 2元素的依此類推。所以,我必須找出最後一個child1元素,它沒有結束。 –

+0

@rohibatta:請更新你的問題比。你提到的最後一個元素沒有「開始」。令人迷惑的人。 –

相關問題