Xpath 표현식에서 작업하는 동안 다른 노드의 한 요소에 종속 된 노드를 찾아야하는 경우가 있습니다.
다음은 사용 된 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>
원하는 출력은 시작 지점이 "Starting"인 노드를 찾은 다음 다른 노드로 이동하는 것입니다 (즉, 노드 외부가 다른 노드에 대해 In) 및 "end"로 끝나지 않음을 의미합니다.
시작과 끝 사이에 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에서 재귀를 찾을 수있는 방법이 있습니까?
이 중복 된 질문에 유래 이미. 그러나 나는 거기에서 해결책을 얻지 못했습니다.
귀하의 요구 사항이 명확하지 않습니다. 내가 이해한다고 생각하는 작은 것부터 두 번에 걸쳐 이것을해야한다고 생각합니다. 여기 부분적인 예가 있습니다.
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>
이제 특정이 노드를 선택하려면이 옵션을 사용할 수 있습니다 (또는없는) start
또는 end
.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다