سؤال

لدي xml أدناه:

<root title="الصفحة الرئيسة">
   <item title="الصفحة الرئيسة" itemuri="tcm:8-29-4" ShowInNav="True" type="sg" pageuri="tcm:8-10592-64" sLink="/ara/index.aspx">
      <item title="من نحن" itemuri="tcm:8-779-4" ShowInNav="True" type="sg" pageuri="tcm:8-9934-64" navorder="00500" sLink="/ara/about/index.aspx">
      </item>
      <item title="برامجنا" itemuri="tcm:8-817-4" ShowInNav="True" type="sg" pageuri="tcm:8-10112-64" navorder="00100" sLink="/ara/courses/language-study-abroad.aspx">
      </item>
      <item title="مدارسنا" itemuri="tcm:8-824-4" ShowInNav="True" type="sg" pageuri="tcm:8-10162-64" navorder="00300" sLink="/ara/schools/english-language.aspx"> 
      </item> 
   </item>
</root>

الآن أريد أن قيمة الحد الأقصى navorder, بحيث يمكنني استخدام تلك القيمة كذلك في "إذا"الشرط.

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

المحلول

أدناه هو XSLT 1.0 رمز اثنين من الحلول الممكنة.

حل ثالث هو استخدام EXSLT.

الرابع الحل هو استخدام maximum قالب من FXSL.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

    <xsl:template match="/">
      <xsl:variable name="vMax1" select=
       "*/*/*/@navorder[not(. &lt; ../../*/@navorder)][3]"/>

       $vMax1: <xsl:value-of select="$vMax1"/>

      <xsl:variable name="vMax2">
        <xsl:call-template name="max">
          <xsl:with-param name="pSeq" 
               select="*/*/*/@navorder"/>
        </xsl:call-template>
      </xsl:variable>

       $vMax2: <xsl:value-of select="$vMax2"/>

    </xsl:template>

    <xsl:template name="max">
      <xsl:param name="pSeq"/>

      <xsl:variable name="vLen" select="count($pSeq)"/>

      <xsl:if test="$vLen > 0">
        <xsl:choose>
          <xsl:when test="$vLen = 1">
            <xsl:value-of select="$pSeq[1]"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:variable name="vHalf" 
             select="floor($vLen div 2)"/>

            <xsl:variable name="vMax1">
              <xsl:call-template name="max">
                <xsl:with-param name="pSeq" 
                 select="$pSeq[not(position() > $vHalf)]"/>
              </xsl:call-template>
            </xsl:variable>

            <xsl:variable name="vMax2">
              <xsl:call-template name="max">
                <xsl:with-param name="pSeq" 
                 select="$pSeq[position() > $vHalf]"/>
              </xsl:call-template>
            </xsl:variable>

            <xsl:choose>
              <xsl:when test="$vMax1 >= $vMax2">
                <xsl:value-of select="$vMax1"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="$vMax2"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
    </xsl:template>
</xsl:stylesheet>

عندما أعلاه transformatio يتم تطبيقها على الأصل مستند XML:

<root title="الصفحة الرئيسة">
    <item title="الصفحة الرئيسة" itemuri="tcm:8-29-4"
          ShowInNav="True" type="sg"
          pageuri="tcm:8-10592-64"
          sLink="/ara/index.aspx">
        <item title="من نحن" itemuri="tcm:8-779-4"
              ShowInNav="True" type="sg"
              pageuri="tcm:8-9934-64"
              navorder="00500"
              sLink="/ara/about/index.aspx"/>
        <item title="برامجنا" itemuri="tcm:8-817-4"
              ShowInNav="True" type="sg"
              pageuri="tcm:8-10112-64"
              navorder="00100"
              sLink="/ara/courses/language-study-abroad.aspx"/>
        <item title="مدارسنا" itemuri="tcm:8-824-4"
              ShowInNav="True" type="sg"
              pageuri="tcm:8-10162-64"
              navorder="00300"
              sLink="/ara/schools/english-language.aspx"/>
  </item>
</root>

من يريد النتيجة المنتجة:

   $vMax1: 00500

   $vMax2: 00500

نصائح أخرى

التالي هو الحل باستخدام XPath 1.0:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
      <xsl:variable name="maximum">
        <xsl:value-of select="/root/item//item[not(preceding-sibling::item/@navorder > @navorder or following-sibling::item/@navorder > @navorder)]/@navorder"/>
      </xsl:variable>
      <max>
        <xsl:value-of select="$maximum"/>
      </max>
    </xsl:template>
</xsl:stylesheet>

التعبير

/root/item//item[not(preceding-sibling::item/@navorder > @navorder or following-sibling::item/@navorder > @navorder)]/@navorder

مرشحات كل بند من العقد بحيث لا يوجد السابقة أو التالية العقدة التي لديها أعلى navorder قيمة على نفس المستوى.

وجدت هذا منتدى آخر باعتبارها أحد الحلول المحتملة.

بالطبع, إذا كان لديك الوصول إلى XPath 2.0 هناك أكثر مباشرة الحل: fn:max(arg, arg, …)

عدة طرق:مع xpath 2 يمكنك استخدام الدالة max (), ولكن إذا كنت في xslt 1 سيكون لديك لاستخدام نوع في مقابل بعضها ثم وضع هذا البند في الموضع 1 في المتغير الخاص بك.

إلقاء نظرة على هذا.ثم استخدامها في xpath

/root/item[@navorder = math:max(/root/item/@navorder)]

أو شيئا من هذا القبيل :)

ملاحظة هذا يتطلب استخدام EXSLT.

ملاحظة 2:لا لا.مجرد نسخ ولصق رمز.

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