xpath "متابعة الأشقاء من قبل"
-
21-09-2019 - |
سؤال
أحاول تحديد عناصر (أ) مع XPath 1.0 (أو ربما يمكن أن يكون مع Regex) التي تتبع الأشقاء لعنصر معين (ب) ولكن فقط قبل عنصر B آخر.
<img><b>First</b><br>
<img> <a href="/first-href">First Href</a> - 19:30<br>
<img><b>Second</b><br>
<img> <a href="/second-href">Second Href</a> - 19:30<br>
<img> <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 />  
<img/>  
<a href="/first-href">First Href</a> - 19:30
<br />
<img/>
<b>Second</b>
<br />
<img/>  
<a href="/second-href">Second Href</a> - 19:30
<br />
<img/> 
<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>