2009-06-08 5 views
6

모든 유용한 답변! 하지만 문제는중첩 된 XPath 조건 사용 ... 세련된

나는 다음과 같은 샘플 XML있어

...

<objects> 
    <object objectId="1123" ... /> 
    <properties refObjectId="1123" ... /> 
    <properties refObjectId="1123" refPropertyId="2311" ... /> 
    <properties refObjectId="1123" refPropertyId="4611" ... /> 
    <object objectId="2123" ... /> 
    <properties refObjectId="2123" refPropertyId="4311" ... /> 
    <properties refObjectId="2123" refPropertyId="8611" ... /> 
    .... 
</objects> 

... 다음과 같은 XPath 쿼리 ...

//object[//properties[@[email protected] and not(@refPropertyId)]] 

생각 ... 정제 가치 이 쿼리는 모든 object 노드를 반환합니다. 노드 에 refObjectId이라는 속성이 있고 object 노드 인 이며 'refPropertyId'속성이없는 노드가있는 노드는 properties입니다. bute ... 즉 객체 1123 만, 객체 2123 ...이 아닙니다. 중첩 된 술어의 @objectIdobject 노드의 objectId 속성을 참조하지 않는 것으로 보입니다.

아이디어가 있으십니까? XML 구조가 예상대로 중첩되지는 않지만이 구조에는 이유가 있습니다.

+0

특정 개체의 속성이 개체 아래에 나타나는 개체 노드 내에 여러 개체 노드가 있습니까? –

답변

7

일반적으로 가능한 경우 //을 사용하지 마십시오. 나는 문구를 수정 고려할 것 :

제공되는 표현에서
//object[../properties/@[email protected]] 

, 당신의 중첩 술어가 실제로 아무도 없습니다있는

//properties/@refObjectId=//properties/@objectId 

를 확인한다.

도움이 되었기를 바랍니다.

EDIT : 업데이트 된 응답은 다음과 같습니다. "중첩 된 조건 자의 @objectId가 개체 노드의 objectId 특성을 참조하지 않는 것 같습니다." 너는 절대적으로 옳다! 그래서 고쳐 주자 !!

//object[../properties[not(@refPropertyId)]/@[email protected]] 

이것은 내가 겪은 것과 더 가깝습니다.

+1

좋은 XPath, Jweede. –

0

이 시도 :

//objects[object/@objectId = properties/@refObjectId]/object 
0

이 작동합니다 :

//objects/object[@objectId = ../properties/@refObjectId] 

나는 당신의 XML이 얼마나 확실하지 않다. 그것은 다음과 같은 형식에있는 경우 :

<objects> 
    <object objectId="1111" /> 
    <properties refObjectId="1111" /> 
    <object objectId="2111" /> 
    <properties refObjectId="3111" /> 
    <object objectId="4111" /> 
    <properties refObjectId="5111" /> 
    <object objectId="6111" /> 
    <properties refObjectId="4111" /> 
    <object objectId="7111" /> 
    <properties refObjectId="7111" /> 
</objects> 

그런 다음 당신이 단지는 1111 끼어 장착 객체를 얻기 위해 다음과 같은 XPath를 사용한다 결과는 4111을 포함하지 않아야 refObjectId = 4111 즉시을 따르지 않는 특성 때문에 objectId = 4111 인 객체.

/objects/properties[ 
    @refObjectId = preceding-sibling::object[1]/@objectId 
    and 
    not(@refPropertyId) 
]/preceding-sibling::object[1] 

이 꽤 잘 수행해야합니다

//objects/properties[@refObjectId = preceding::object[1]/@objectId]/preceding::object[1] 
0

은 주어진 <object>에 속하는 모든 <properties> 노드가 실제로 객체를 따르는 것이 가정하면, 당신은 할 수 있습니다 (귀하의 의견은을 암시하는 것 같다).당신이 XSLT에 될 일 경우

, 일이 많은 간단하게 얻을 :

<xsl:key name="kPropertiesByObjectId" match="properties" use="@refObjectId" /> 

과 XSLT의 경우

<xsl:template match="object"> 
    <!-- This tests for an empty node-set. Non-empty node sets can only happen 
     for objects with at least one <properties> node without @refPropertyId --> 
    <xsl:if test="key('kPropertiesByObjectId', @objectId)[not(@refPropertyId)]"> 
    <xsl:copy-of select="." /> 
    </xsl:if> 
</xsl:template> 

는, 객체와 proerties 노드의 순서는 무관된다.