سؤال

لدي XML

<Root>
  <Parent>
    <Child1>A</Child1>
    <Child2>B</Child2>
    <Child1>X</Child1>
    <Child2>Y</Child2>
  </Parent>
</Root>

الطفل 2 دائما سيكون مع الطفل 1. أحتاج إلى معرفة كيف يمكنني استخدام استخدام xsl:foreach وإنشاء مثال إخراج XML.

<TransformedXML>
  <Child attribute1="A" attribute2="B"/>
  <Child attribute1="X" attribute2="Y"/>
</TransformedXML>

سؤالي هو كيف يمكنني حلقة XSLT مع الأخذ في الاعتبار أن عقدة الطفل 2 ستتبع طفل 1 دائمًا؟

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

المحلول

هذا التحول:

<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:key name="kFollowingChild1" match="*[not(self::Child1)]"
  use="generate-id(preceding-sibling::Child1[1])"/>

 <xsl:template match="Parent">
  <TransformedXML>
   <xsl:apply-templates/>
  </TransformedXML>
 </xsl:template>

 <xsl:template match="Child1">
  <Child>
   <xsl:for-each select=".|key('kFollowingChild1', generate-id())">
    <xsl:attribute name="attribute{position()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
   </xsl:for-each>
  </Child>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

عند تطبيقها على المقدمة (تم تصحيحها عدة مرات لتصبح مستندًا جيدًا!):

<Root>
    <Parent>
        <Child1>A</Child1>
        <Child2>B</Child2>
        <Child1>X</Child1>
        <Child2>Y</Child2>
    </Parent>
</Root>

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

<TransformedXML>
   <Child attribute1="A" attribute2="B"/>
   <Child attribute1="X" attribute2="Y"/>
</TransformedXML>

نصائح أخرى

هل هناك سبب محدد لاستخدامك xsl:for-each؟ أقترح فقط استخدام قوالب مطابقة:

<xsl:template match="Child1">
  <Child attribute1="{.}" attribute2="{following-sibling::*[1]}"/>
</xsl:template>

<xsl:template match="Child2"/>

هذا سيعمل بشكل جيد طالما أن الشرط المسبق Child1 ستكون دائمًا أول شقيق يلي Child2.

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