ฉันใหม่ใน XSLT ดังนั้นฉันจึงสับสนเล็กน้อยเกี่ยวกับสองแท็ก
<xsl:apply-templates name="nodes">
และ
<xsl:call-template select="nodes">
คุณสามารถระบุความแตกต่างระหว่างพวกเขาได้หรือไม่?
ฉันใหม่ใน XSLT ดังนั้นฉันจึงสับสนเล็กน้อยเกี่ยวกับสองแท็ก
<xsl:apply-templates name="nodes">
และ
<xsl:call-template select="nodes">
คุณสามารถระบุความแตกต่างระหว่างพวกเขาได้หรือไม่?
คำตอบ:
<xsl:call-template>
ใกล้เคียงกับการเรียกใช้ฟังก์ชันในภาษาโปรแกรมแบบดั้งเดิม
คุณสามารถกำหนดฟังก์ชันใน XSLT ได้เช่นเดียวกับฟังก์ชันง่ายๆนี้ที่ส่งออกสตริง
<xsl:template name="dosomething">
<xsl:text>A function that does something</xsl:text>
</xsl:template>
<xsl:call-template name="dosomething">
ฟังก์ชั่นนี้สามารถเรียกผ่าน
<xsl:apply-templates>
แตกต่างกันเล็กน้อยและในนั้นคือพลังที่แท้จริงของ XSLT: ใช้โหนด XML จำนวนเท่าใดก็ได้ (สิ่งที่คุณกำหนดในselect
แอตทริบิวต์) ทำซ้ำ ( สิ่งนี้สำคัญ: ใช้เทมเพลตทำงานเหมือนวนซ้ำ! ) และค้นหาเทมเพลตที่ตรงกัน สำหรับพวกเขา:
<!-- sample XML snippet -->
<xml>
<foo /><bar /><baz />
</xml>
<!-- sample XSLT snippet -->
<xsl:template match="xml">
<xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>
<xsl:template match="foo"> <!-- will be called once -->
<xsl:text>foo element encountered</xsl:text>
</xsl:template>
<xsl:template match="*"> <!-- will be called twice -->
<xsl:text>other element countered</xsl:text>
</xsl:template>
วิธีนี้ทำให้คุณเลิกควบคุมโปรเซสเซอร์ XSLT เพียงเล็กน้อย - ไม่ใช่คุณตัดสินใจว่าโฟลว์ของโปรแกรมจะไปที่ใด แต่โปรเซสเซอร์ทำโดยการค้นหาการจับคู่ที่เหมาะสมที่สุดสำหรับโหนดที่กำลังประมวลผลอยู่
หากหลายเทมเพลตสามารถจับคู่กับโหนดได้เทมเพลตที่มีนิพจน์การจับคู่เฉพาะเจาะจงมากขึ้นจะชนะ หากมีเทมเพลตที่ตรงกันมากกว่าหนึ่งรายการที่มีความเฉพาะเจาะจงเดียวกันเทมเพลตที่ประกาศว่าชนะครั้งสุดท้าย
คุณสามารถมีสมาธิในการพัฒนาเทมเพลตได้มากขึ้นและใช้เวลาในการทำ "ประปา" น้อยลง โปรแกรมของคุณจะมีประสิทธิภาพมากขึ้นและเป็นโมดูลาร์ซ้อนกันน้อยลงและเร็วขึ้น (เนื่องจากโปรเซสเซอร์ XSLT ได้รับการปรับให้เหมาะสมสำหรับการจับคู่เทมเพลต)
แนวคิดที่ต้องทำความเข้าใจกับ XSLT คือ "โหนดปัจจุบัน" เมื่อ<xsl:apply-templates>
โหนดปัจจุบันย้ายไปพร้อมกับการทำซ้ำทุกครั้งในขณะที่<xsl:call-template>
ไม่เปลี่ยนโหนดปัจจุบัน กล่าวคือ.
ภายในเทมเพลตที่เรียกว่าหมายถึงโหนดเดียวกันกับ.
ในเทมเพลตการโทร นี่ไม่ใช่กรณีที่ใช้เทมเพลต
นี่คือความแตกต่างพื้นฐาน มีลักษณะอื่น ๆ ของเทมเพลตที่ส่งผลต่อพฤติกรรมของพวกเขา: เทมเพลตmode
และpriority
ความจริงที่ว่าเทมเพลตสามารถมีได้ทั้ง a name
และmatch
. นอกจากนี้ยังมีผลกระทบว่ามีการนำเข้าเทมเพลต ( <xsl:import>
) หรือไม่ สิ่งเหล่านี้เป็นการใช้งานขั้นสูงและคุณสามารถจัดการได้เมื่อไปถึงที่นั่น
<xsl:apply-templates>
ทำตัวเหมือนวนซ้ำ ความแตกต่างของการนำไปใช้งานในส่วนท้ายของโปรเซสเซอร์ XSLT จะไม่ส่งผลกระทบต่อฉันในฐานะโปรแกรมเมอร์ XSLT ผลลัพธ์จะเหมือนกันอย่างแน่นอนสำหรับการใช้งานแบบขนานและแบบวนซ้ำ แต่สำหรับมือใหม่ XSLT ที่มีภูมิหลังที่จำเป็นจะช่วยให้จินตนาการได้<xsl:apply-templates>
ว่าเป็นแบบสำหรับแต่ละลูปแม้ว่าในทางเทคนิคจะไม่ใช่ก็ตาม
หากต้องการเพิ่มคำตอบที่ดีโดย @Tomalak:
ความแตกต่างที่สำคัญและไม่ได้กล่าวถึงมีดังนี้:
xsl:apply-templates
มากยิ่งขึ้นและลึกกว่าxsl:call-templates
และแม้กระทั่งจาก xsl:for-each
,เพียงเพราะเราไม่ทราบว่ารหัสจะนำไปใช้บนโหนดของการเลือก - ในกรณีทั่วไปรหัสนี้จะแตกต่างกันสำหรับโหนดที่แตกต่างกันของโหนดรายการ
รหัสที่จะนำไปใช้สามารถเขียนได้หลังจากxsl:apply template
เขียน sและโดยบุคคลที่ไม่รู้จักผู้เขียนต้นฉบับ
การใช้ไลบรารี FXSLของฟังก์ชันลำดับที่สูงขึ้น (HOF) ใน XSLT จะไม่สามารถทำได้หาก XSLT ไม่มี<xsl:apply-templates>
คำสั่ง
สรุป : เทมเพลตและ<xsl:apply-templates>
คำแนะนำคือวิธีที่ XSLT ใช้และจัดการกับความหลากหลาย
อ้างอิง : ดูหัวข้อทั้งหมดนี้: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html
xsl:apply-templates
โดยปกติจะใช้ (แต่ไม่จำเป็น) เพื่อประมวลผลชายน์ทั้งหมดหรือส่วนย่อยของโหนดปัจจุบันด้วยเทมเพลตที่เกี่ยวข้องทั้งหมด สิ่งนี้สนับสนุนการเรียกซ้ำของแอ็พพลิเคชัน XSLT ซึ่งตรงกับการเรียกซ้ำ (เป็นไปได้) ของ XML ที่ประมวลผล
xsl:call-template
ในทางกลับกันก็เหมือนกับการเรียกใช้ฟังก์ชันทั่วไป คุณเรียกใช้เทมเพลต (ชื่อ) หนึ่งเทมเพลตโดยปกติจะมีพารามิเตอร์อย่างน้อยหนึ่งตัว
ดังนั้นฉันจึงใช้xsl:apply-templates
ถ้าฉันต้องการสกัดกั้นการประมวลผลของโหนดที่น่าสนใจและ (โดยปกติ) จะฉีดอะไรบางอย่างลงในสตรีมเอาต์พุต ตัวอย่างทั่วไป (แบบง่าย) จะเป็น
<xsl:template match="foo">
<bar>
<xsl:apply-templates/>
</bar>
</xsl:template>
ในขณะที่xsl:call-template
ฉันมักจะแก้ปัญหาเช่นการเพิ่มข้อความของโหนดย่อยบางโหนดเข้าด้วยกันการเปลี่ยนชุดโหนดที่เลือกให้เป็นข้อความหรือชุดโหนดอื่น ๆ และสิ่งที่คล้ายกัน - อะไรก็ตามที่คุณจะเขียนฟังก์ชันพิเศษที่ใช้ซ้ำได้
เป็นข้อสังเกตเพิ่มเติมสำหรับข้อความคำถามเฉพาะของคุณ:
<xsl:call-template name="nodes"/>
สิ่งนี้เรียกเทมเพลตที่มีชื่อว่า 'nodes':
<xsl:template name="nodes">...</xsl:template>
นี่เป็นความหมายที่แตกต่างจาก:
<xsl:apply-templates select="nodes"/>
... ซึ่งใช้แม่แบบทั้งหมดกับลูกทั้งหมดของโหนด XML ปัจจุบันของคุณที่มีชื่อเป็น 'โหนด'
ฟังก์ชันการทำงานนั้นคล้ายคลึงกันมาก (นอกเหนือจากการเรียกความหมายโดยที่call-template
ต้องใช้name
แอตทริบิวต์และเทมเพลตชื่อที่เกี่ยวข้อง)
อย่างไรก็ตามโปรแกรมแยกวิเคราะห์จะไม่ดำเนินการในลักษณะเดียวกัน
จากMSDN :
ซึ่งแตกต่าง
<xsl:apply-templates>
,<xsl:call-template>
ไม่เปลี่ยนแปลงโหนดปัจจุบันหรือในปัจจุบันโหนดรายการ
<xsl:apply-templates>
ต้องนำมาใช้เป็นลูป - ในทางกลับกันอาจใช้งานควบคู่กันได้เนื่องจากแอปพลิเคชันที่แตกต่างกันบนโหนดต่างๆของรายการโหนดนั้นเป็นอิสระจากกันอย่างแน่นอน