سؤال

لدي XML يسير على هذا النحو:

<company>
    <employee name="john"/>
    <employee name="sarah"/>
    <employee name="kim"/>
    <employee name="karl"/>
    <employee name="tom"/>
    <employee name="jim"/>
    <employee name="sandy"/>
</company>

كيف يمكنني استخدام قالب XSLT لاختيار العقد الأولى فقط ، 3 على سبيل المثال ، حتى أتمكن من الحصول على:

<company>
    <employee name="john"/>
    <employee name="sarah"/>
    <employee name="kim"/>
</company>

في محرر Oxygen XML ، يمكنني استخدام XPath التالي لتحقيق ذلك:

/company/employee[position() < (last() - count(/company/employee)+4)]

لكنني حقًا بحاجة إلى استخدام XSLT في هذه الحالة
شكرا لمساعدتك

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

المحلول

كيف يمكنني استخدام قالب XSLT لاختيار العقد الأولى فقط ، 3 على سبيل المثال ، حتى أتمكن من الحصول على:

<company> 
    <employee name="john"/> 
    <employee name="sarah"/> 
    <employee name="kim"/> 
</company>

الجواب القصير: من خلال معرفة القليل من XPath و XSLT.

الإجابة الكاملة (ولكن لا تزال قصيرة):

هذا التحول:

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

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="employee[position() > 3]"/>
</xsl:stylesheet>

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

<company>
    <employee name="john"/>
    <employee name="sarah"/>
    <employee name="kim"/>
    <employee name="karl"/>
    <employee name="tom"/>
    <employee name="jim"/>
    <employee name="sandy"/>
</company>

تنتج النتيجة الصحيحة المطلوبة:

<company>
   <employee name="john"/>
   <employee name="sarah"/>
   <employee name="kim"/>
</company>

القيام مذكرة:

  1. ال قاعدة الهوية يستخدم لنسخ كل عقدة "كما هو".

  2. هناك قالب واحد فقط يتجاوز قالب الهوية. يطابق أي employee العنصر مع الموضع في قائمة العقدة أكبر من 3. يحتوي هذا القالب على جسم فارغ ، يتجاهل بشكل فعال العناصر المتطابقة.

نصائح أخرى

يمكنني استخدام XPath التالي لتحقيق ذلك:

/company/employee[position() < (last() - count(/company/employee)+4)]

لاحظ ذلك هنا last() مساوي ل count(/company/employee), ، لذلك سيتم تقليل هذا إلى:

/company/employee[4 > position()]

في نمط يمكن أن يكون لديك:

<xsl:template match="employee[4 > position()]">    
...
</xsl:template>

الشيء نفسه مع المعلمة (Remenber لا يمكنك استخدام مرجع المعلمة في أنماط XSLT 1.0):

<xsl:param name="pTop" select="3"/>    

<xsl:template match="employee">    
   <xsl:if test="$pTop >= position()">    
   ...
   </xsl:if>
</xsl:template>

جرب هذا:

<xsl:for-each select="company/employee[position() &lt; 3]">
  ...
</xsl:for-each>

هذا قد يعمل مع <template select=.... أيضًا لكنني لست متأكدًا.

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