2015-09-30 55 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:请更新你的问题比。你提到的最后一个元素没有“开始”。令人迷惑的人。 –

相关问题