IT story

xpath를 사용하여 노드 위치 찾기

hot-time 2020. 9. 16. 21:00
반응형

xpath를 사용하여 노드 위치 찾기


누구나 xpath를 사용하여 노드의 위치를 ​​얻는 방법을 알고 있습니까?

다음 xml이 있다고 가정하십시오.

<a>
    <b>zyx</b>
    <b>wvu</b>
    <b>tsr</b>
    <b>qpo</b>
</a>

다음 xpath 쿼리를 사용하여 세 번째 <b> 노드 (<b> tsr </ b>)를 선택할 수 있습니다.

a/b[.='tsr']

모두 훌륭하고 좋지만 다음과 같이 해당 노드의 서수 위치 반환 하고 싶습니다.

a/b[.='tsr']/position()

(하지만 조금 더 작동합니다!)

가능할까요?

편집 : .net 2를 사용하고 있다는 것을 언급하는 것을 잊었으므로 xpath 1.0입니다!


업데이트 : James Sulak훌륭한 대답을 사용하여 끝났습니다 . 관심이있는 사람들을 위해 C #으로 구현 한 내용은 다음과 같습니다.

int position = doc.SelectNodes("a/b[.='tsr']/preceding-sibling::b").Count + 1;

// Check the node actually exists
if (position > 1 || doc.SelectSingleNode("a/b[.='tsr']") != null)
{
    Console.WriteLine("Found at position = {0}", position);
}

시험:

count(a/b[.='tsr']/preceding-sibling::*)+1.

XSLT로 이것을 할 수 있지만 직선 XPath에 대해 잘 모르겠습니다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8" indent="yes" 
              omit-xml-declaration="yes"/>
  <xsl:template match="a/*[text()='tsr']">
    <xsl:number value-of="position()"/>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

게시물이 고대라는 걸 알지만 ..

별표를 노드 이름으로 바꾸면 더 나은 결과를 얻을 수 있습니다.

count(a/b[.='tsr']/preceding::a)+1.

대신에

count(a/b[.='tsr']/preceding::*)+1.

XPath 2.0으로 업그레이드 한 경우 index-of 함수를 제공 하므로 다음과 같이 문제가 해결됩니다.

index-of(//b, //b[.='tsr'])

어디:

  • 첫 번째 매개 변수는 검색 순서입니다.
  • 두 번째는 무엇을 검색 할 것인가

앞서 언급 한 'preceding-sibling'은 완전히 다른 일을하는 'preceding'이 아니라 실제로 사용할 축이며 현재 노드의 시작 태그 앞에있는 문서의 모든 것을 선택합니다. ( http://www.w3schools.com/xpath/xpath_axes.asp 참조 )


James Sulak의 답변에 대한 메모입니다.

노드가 존재하지 않을 수 있다는 것을 고려하고 순수하게 XPATH를 유지하려면 노드가 존재하지 않으면 0을 반환하는 다음을 시도하십시오.

count(a/b[.='tsr']/preceding-sibling::*)+number(boolean(a/b[.='tsr']))

문제는 노드의 위치가 컨텍스트 없이는 그다지 의미가 없다는 것입니다.

The following code will give you the location of the node in its parent child nodes

using System;
using System.Xml;

public class XpathFinder
{
    public static void Main(string[] args)
    {
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.Load(args[0]);
        foreach ( XmlNode xn in xmldoc.SelectNodes(args[1]) )
        {
            for (int i = 0; i < xn.ParentNode.ChildNodes.Count; i++)
            {
                if ( xn.ParentNode.ChildNodes[i].Equals( xn ) )
                {
                    Console.Out.WriteLine( i );
                    break;
                }
            }
        }
    }
}

I do a lot of Novell Identity Manager stuff, and XPATH in that context looks a little different.

Assume the value you are looking for is in a string variable, called TARGET, then the XPATH would be:

count(attr/value[.='$TARGET']/preceding-sibling::*)+1

Additionally it was pointed out that to save a few characters of space, the following would work as well:

count(attr/value[.='$TARGET']/preceding::*) + 1

I also posted a prettier version of this at Novell's Cool Solutions: Using XPATH to get the position node

참고URL : https://stackoverflow.com/questions/226405/find-position-of-a-node-using-xpath

반응형