سؤال

أحد يعرف كيفية الحصول على موقف من عقدة باستخدام 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()

(ولكن أكثر قليلا من العمل!)

هل من الممكن ؟

تحرير:نسيت أن أذكر أنا باستخدام .صافي 2 حتى انها xpath 1.0!


التحديث:انتهت باستخدام جيمس Sulak's ممتازة الإجابة.بالنسبة لأولئك الذين يرغبون هنا هو بلدي التنفيذ في 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.

خلافا ذكر سابقا 'السابقة-الأخوة' هو في الحقيقة محور الاستخدام, لا 'السابق' التي لا شيء مختلف تماما ، فإنه يختار كل شيء في المستند الذي يتم قبل بداية الوسم العقدة الحالية.(انظر http://www.w3schools.com/xpath/xpath_axes.asp)

إذا كنت من أي وقت مضى الترقية إلى XPath 2.0, علما أنه يوفر وظيفة مؤشر من, ذلك لن يحل المشكلة بهذه الطريقة:

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

حيث:

  • 1 المعلمة تسلسل البحث
  • 2 هو ما يجب البحث

فقط ملاحظة الجواب به جيمس Sulak.

إذا كنت تريد أن تأخذ في الاعتبار أن عقدة قد لا تكون موجودة ونريد أن نحافظ عليها بحتة XPATH, ثم حاول بعد ذلك سيعود 0 إذا كانت العقدة لا وجود لها.

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

المشكلة هي أن موقف عقدة لا يعني الكثير دون سياق.

التعليمة البرمجية التالية سوف تعطيك موقع العقدة في الأم الطفل العقد

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;
                }
            }
        }
    }
}

أفعل الكثير من Novell الهوية مدير الأشياء و XPATH في هذا السياق تبدو مختلفة قليلا.

نفترض قيمة كنت أبحث عنه في سلسلة متغير يسمى الهدف ، ثم XPATH ليكون:

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

بالإضافة إلى ذلك أشير إلى أن لإنقاذ عدد قليل من الشخصيات من الفضاء التالية من شأنه أن تعمل بشكل جيد:

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

كما نشرت نسخة أجمل من هذا في Novell بارد الحلول: باستخدام XPATH للحصول على موقف عقدة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top