سؤال

أحاول تحديد عناصر (أ) مع XPath 1.0 (أو ربما يمكن أن يكون مع Regex) التي تتبع الأشقاء لعنصر معين (ب) ولكن فقط قبل عنصر B آخر.

<img><b>First</b><br>&nbsp;&nbsp;
<img>&nbsp;&nbsp;<a href="/first-href">First Href</a> - 19:30<br>
<img><b>Second</b><br>&nbsp;&nbsp;
<img>&nbsp;&nbsp;<a href="/second-href">Second Href</a> - 19:30<br>
<img>&nbsp;&nbsp;<a href="/third-href">Third Href</a> - 19:30<br>

حاولت أن أجعل العينة أقرب إلى العالم الحقيقي قدر الإمكان. لذلك في هذا السيناريو عندما أكون في عنصر

<b>First</b>

أنا بحاجة للاختيار

<a href="/first-href">First Href</a> 

وعندما أكون في

<b>Second</b> 

أنا بحاجة للاختيار

<a href="/second-href">Second Href</a> 
<a href="/third-href">Third Href</a>

أي فكرة عن كيفية تحقيق ذلك؟ شكرًا لك!

هل كانت مفيدة؟

المحلول

قم بإنشاء هذا XPath ديناميكيًا:

following-sibling::a[preceding-sibling::b[1][.='xxxx']]

حيث يتم استبدال "xxxx" بنص التيار <b>.

هذا يفترض أن جميع العناصر في الواقع نكون أخوة. إذا لم تكن كذلك ، يمكنك محاولة العمل مع preceding و following المحاور ، أو تكتب XPath أكثر تحديدًا يشبه بنية المستند بشكل أفضل.

في XSLT ، يمكنك أيضًا استخدام:

following-sibling::a[
  generate-id(preceding-sibling::b[1]) = generate-id(current())
]

نصائح أخرى

هنا حل هو مجرد تعبير xpath.

استخدام صيغة كسيسية للتقاطع من اثنين من العقد $ns1 و $ns2:

  $ns1[count(. | $ns2) = count($ns2)]

نحن ببساطة استبدل $ns1 مع العقد <a> الأشقاء الذين يتبعون التيار <b> العقدة ، ونحن نحل محل $ns2 مع العقد <a> الأشقاء الذين يسبقون التالي <b> العقدة.

هنا تحول كامل يستخدم هذا:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
   <xsl:apply-templates select="*/b"/>
  </xsl:template>

  <xsl:template match="b">
    At: <xsl:value-of select="."/>

    <xsl:variable name="vNextB" select="following-sibling::b[1]"/>

    <xsl:variable name="vA-sAfterCurrentB" select="following-sibling::a"/>

    <xsl:variable name="vA-sBeforeNextB" select=
    "$vNextB/preceding-sibling::a
    |
     $vA-sAfterCurrentB[not($vNextB)]
    "/>

    <xsl:copy-of select=
     "$vA-sAfterCurrentB
              [count(.| $vA-sBeforeNextB)
              =
               count($vA-sBeforeNextB)
               ]
    "/>
  </xsl:template>
</xsl:stylesheet>

عندما يتم تطبيق هذا التحول على مستند XML التالي:

<t>
    <img/>
    <b>First</b>
    <br />&#xA0;&#xA0;
    <img/>&#xA0;&#xA0;
    <a href="/first-href">First Href</a> - 19:30
    <br />
    <img/>
    <b>Second</b>
    <br />
    <img/>&#xA0;&#xA0;
    <a href="/second-href">Second Href</a> - 19:30
    <br />
    <img/>&#xA0;
    <a href="/third-href">Third Href</a> - 19:30
    <br />
</t>

يتم إنتاج النتيجة الصحيحة:

   At: First <a href="/first-href">First Href</a>
    At: Second <a href="/second-href">Second Href</a>
<a href="/third-href">Third Href</a>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top