การสร้างบรรทัดใหม่ใน XSLT


198

ฉันต้องการสร้างบรรทัดใหม่สำหรับการแสดงผลข้อความใน XSLT ความคิดใด ๆ


11
ผมคิดว่ามันถึงเวลาที่จะยอมรับคำตอบ :)
Florjon

คำตอบ:


240

รหัส XSL ต่อไปนี้จะสร้างอักขระขึ้นบรรทัดใหม่ (ตัวดึงบรรทัด):

<xsl:text>&#xa;</xsl:text>

สำหรับการรับคืนรถใช้:

<xsl:text>&#xd;</xsl:text>

7
+1: สิ่งนี้มีประสิทธิภาพมากกว่า<xsl:text>วิธีการขึ้นบรรทัดใหม่ที่มีหากคุณใช้สิ่งใดก็ตามที่อาจฟอร์แมตไฟล์ XSL ของคุณอีกครั้งและยุ่งกับช่องว่าง
Ian Roberts

49

วิธีที่ฉันชอบในการทำสิ่งนี้ดูเหมือนว่า:

<xsl:stylesheet>

<xsl:output method='text'/>

<xsl:variable name='newline'><xsl:text>
</xsl:text></xsl:variable>

<!-- note that the layout there is deliberate -->

...

</xsl:stylesheet>

จากนั้นเมื่อใดก็ตามที่คุณต้องการส่งออกบรรทัดใหม่ (อาจเป็น csv) คุณสามารถส่งออกบางสิ่งดังนี้:

<xsl:value-of select="concat(elem1,elem2,elem3,$newline)" />

ฉันใช้เทคนิคนี้เมื่อแสดงผล sql จากอินพุต xml ที่จริงแล้วฉันมักจะสร้างตัวแปรสำหรับเครื่องหมายจุลภาคราคาและบรรทัดใหม่


3
โปรดทราบว่าคำตอบของ Florjon ด้านล่างมีความเสถียรมากกว่าของฉันมาก
Nic Gibson

1
มันอาจจะคุ้มค่าการเพิ่มการประกาศxml:space="preserve"กับxsl:textองค์ประกอบเพื่อความมั่นคงเพิ่มขึ้น แต่ฉันยอมรับว่าคำตอบ @ Florjon คืออาจจะปลอดภัยกว่า
Flynn1179

วิธีนี้มีข้อเสียเปรียบของการรวมถึงการเยื้องซึ่งอาจไม่พึงประสงค์
wmassingham

47

รวมแอตทริบิวต์ Method = "text" บนแท็ก xsl: output และรวมบรรทัดใหม่ในเนื้อหาตามตัวอักษรของคุณใน XSL ที่จุดที่เหมาะสม หากคุณต้องการเก็บซอร์สโค้ดของ XSL ที่เป็นระเบียบใช้เอนทิตี&#10;ที่คุณต้องการขึ้นบรรทัดใหม่


31

คุณสามารถใช้ได้: <xsl:text>&#10;</xsl:text>

ดูตัวอย่าง

<xsl:variable name="module-info">
  <xsl:value-of select="@name" /> = <xsl:value-of select="@rev" />
  <xsl:text>&#10;</xsl:text>
</xsl:variable>

ถ้าคุณเขียนมันลงในไฟล์เช่น

<redirect:write file="temp.prop" append="true">
  <xsl:value-of select="$module-info" />
</redirect:write>

ตัวแปรนี้จะสร้าง infile บรรทัดใหม่เมื่อ:

commons-dbcp_commons-dbcp = 1.2.2
junit_junit = 4.4
org.easymock_easymock = 2.4

6

IMHO ไม่ต้องการข้อมูลเพิ่มเติมเกินกว่าที่ @Florjon มอบให้ อาจมีรายละเอียดเล็ก ๆ น้อย ๆ ที่ทำให้เข้าใจว่าทำไมบางครั้งมันอาจไม่ได้ผล

ก่อนอื่นเลย&#xa(hex) หรือ&#10(dec) ภายใน a <xsl:text/>จะใช้ได้เสมอ แต่คุณอาจไม่เห็น

  1. ไม่มีการขึ้นบรรทัดใหม่ในมาร์กอัพ HTML ใช้ง่าย<br/>จะทำได้ดี มิฉะนั้นคุณจะเห็นพื้นที่สีขาว การดูแหล่งที่มาจากเบราว์เซอร์จะบอกคุณว่าเกิดอะไรขึ้นจริง ๆ อย่างไรก็ตามมีบางกรณีที่คุณคาดหวังพฤติกรรมนี้โดยเฉพาะหากผู้บริโภคไม่ได้เป็นเบราว์เซอร์โดยตรง ตัวอย่างเช่นคุณต้องการสร้างหน้า HTML และดูโครงสร้างของมันในรูปแบบที่มีบรรทัดว่างและเหตุการณ์ก่อนที่จะแสดงในเบราว์เซอร์
  2. จำไว้ว่าคุณต้องใช้disable-output-escapingที่ไหนและทำที่ไหน ใช้ตัวอย่างต่อไปนี้ที่ฉันต้องสร้าง xml จากที่อื่นและประกาศ DTD จากสไตล์ชีท

รุ่นแรกหนีอักขระ (ค่าเริ่มต้นสำหรับ xsl: text)

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

    <xsl:template match="/">
        <xsl:text>&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>
        <xsl:copy>
            <xsl:apply-templates select="*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*|node()" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" mode="copy"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

และนี่คือผลลัพธ์:

<?xml version="1.0" encoding="utf-8"?>
&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;

&#13;<Subscriptions>
    <User id="1"/>   
</Subscriptions>

ตกลงมันทำในสิ่งที่เราคาดหวังการหลบหนีจะทำเพื่อให้ตัวละครที่เราใช้นั้นแสดงอย่างถูกต้อง ส่วนการจัดรูปแบบ XML ident="yes"ภายในโหนดรากจะถูกจัดการโดย แต่ด้วยมุมมองที่ใกล้ชิดเราเห็นว่าตัวละครขึ้นบรรทัดใหม่&#xaไม่ได้หลบหนีและแปลตามที่เป็นอยู่แสดงการป้อนบรรทัดสองครั้ง! ฉันไม่มีคำอธิบายเกี่ยวกับเรื่องนี้จะดีที่จะรู้ ใคร?

รุ่นที่สองไม่ได้หนีจากตัวละครดังนั้นพวกเขาจึงผลิตสิ่งที่พวกเขาต้องการ การเปลี่ยนแปลงที่เกิดขึ้นคือ:

<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>

และนี่คือผลลัพธ์:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">

<Subscriptions>
    <User id="1"/>   
</Subscriptions>

และนั่นจะไม่เป็นไร ทั้ง cr และ lf แสดงผลอย่างเหมาะสม

  1. อย่าลืมว่าเรากำลังพูดถึงnlไม่ใช่crlf( nl=lf) ความพยายามครั้งแรกของฉันคือการใช้ cr เท่านั้น&#xdและในขณะที่เอาต์พุต xml ได้รับการตรวจสอบโดย DOM อย่างถูกต้อง

ฉันดู xml ที่เสียหาย:

<?xml version="1.0" encoding="utf-8"?>
<Subscriptions>riptions SYSTEM "Subscriptions.dtd">
    <User id="1"/>   
</Subscriptions>

parser DOM ไม่สนใจอักขระควบคุม แต่การแสดงผลไม่ได้ ฉันใช้เวลาค่อนข้างชนกระแทกหัวของฉันก่อนที่ฉันจะรู้ว่าโง่ฉันไม่ได้เห็นสิ่งนี้!

สำหรับบันทึกฉันใช้ตัวแปรภายในร่างกายด้วย CRLF ทั้งสองเพื่อให้แน่ใจว่ามันจะทำงานได้ทุกที่ 100%


4

ฉันได้เพิ่มDOCTYPEคำสั่งที่คุณเห็นที่นี่:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY nl "&#xa;">
]>
<xsl:stylesheet xmlns:x="http://www.w3.org/2005/02/query-test-XQTSCatalog"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

สิ่งนี้ช่วยให้ฉันใช้&nl;แทน&#xa;การสร้างบรรทัดใหม่ในผลลัพธ์ เช่นเดียวกับโซลูชันอื่น ๆ โดยทั่วไปจะอยู่ภายใน<xsl:text>แท็ก



2

ฉันใช้วิธีที่สองของ Nic Gibson นี่เป็นสิ่งที่ฉันชอบเสมอ:

<xsl:variable name='nl'><xsl:text>
</xsl:text></xsl:variable>

อย่างไรก็ตามฉันได้ใช้งาน Ant <echoxml> เพื่อสร้างสไตล์ชีทและใช้มันกับไฟล์ งานจะทำเทมเพลตค่าแอตทริบิวต์เช่น $ {DSTAMP} แต่จะทำการฟอร์แมต xml ของคุณอีกด้วยดังนั้นในบางกรณีการอ้างอิงเอนทิตีก็จะดีกว่า

<xsl:variable name='nl'><xsl:text>&#xa;</xsl:text></xsl:variable>

3
หากคุณใช้ตัวแปรมันจะดีกว่าที่จะใช้แทนselect xsl:textตัวอย่าง: <xsl:variable name="nl" select="'&#xA;'"/>วิธีนี้คุณไม่ต้องสร้าง RTF ที่ไม่จำเป็น
Daniel Haley

2

ฉันได้พบความแตกต่างระหว่างการขึ้นบรรทัดใหม่ในตัวอักษรและการขึ้นบรรทัดใหม่โดยใช้ตัวอักษร<xsl:text>&#xA;

ในขณะที่การขึ้นบรรทัดใหม่ตัวอักษรทำงานได้ดีในสภาพแวดล้อมของฉัน (ใช้ทั้งแซกซอนและตัวประมวลผล Java XSLT เริ่มต้น) รหัสของฉันล้มเหลวเมื่อมันถูกเรียกใช้โดยกลุ่มอื่นที่ทำงานในสภาพแวดล้อม. NET

การเปลี่ยนเอนทิตี ( &#xA;) ทำให้โค้ดการสร้างไฟล์ของฉันทำงานอย่างสม่ำเสมอทั้งบน Java และ. NET

นอกจากนี้บรรทัดใหม่ตามตัวอักษรยังมีความเสี่ยงที่จะถูกฟอร์แมตใหม่โดย IDE และอาจหายไปโดยไม่ตั้งใจเมื่อไฟล์นั้นถูกดูแลโดยคนที่ 'ไม่ทราบ'


2

ฉันได้สังเกตเห็นจากประสบการณ์ของฉันที่ผลิตบรรทัดใหม่ภายใน<xsl:variable>ข้อไม่ทำงาน ฉันพยายามทำสิ่งที่ชอบ:

<xsl:variable name="myVar">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
      <xsl:text></xsl:text> <!--NEW LINE-->
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

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

อะไรก็ตามที่ฉันพยายามจะใส่ใน "บรรทัดใหม่" ( <xsl:text>โหนดว่างเปล่า) ก็ไม่ได้ผล (รวมถึงคำแนะนำที่ง่ายที่สุดในหน้านี้) ไม่ต้องพูดถึงข้อเท็จจริงที่ว่า HTML จะไม่ทำงานที่นั่นดังนั้นในที่สุดฉันก็ ต้องแยกมันออกเป็น 2 ตัวแปรเรียกพวกมันออกไปนอก<xsl:variable>ขอบเขตและทำให้ง่าย ๆ<br/>ระหว่างพวกเขาคือ:

<xsl:variable name="myVar1">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<xsl:variable name="myVar2">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<div>
  <xsl:value-of select="$myVar1"/>
  <br/>
  <xsl:value-of select="$myVar2"/>
</div>

ใช่ฉันรู้ว่ามันไม่ใช่วิธีที่ซับซ้อนที่สุด แต่ใช้งานได้เพียงแบ่งปันประสบการณ์ความหงุดหงิดของฉันกับ XSLs;)


2

ฉันไม่สามารถใช้<xsl:text>&#xa;</xsl:text>วิธีนี้ได้เพราะถ้าฉันจัดรูปแบบไฟล์ XML โดยใช้ XSLT เอนทิตีจะหายไป ดังนั้นฉันจึงต้องใช้รอบเพิ่มเติมเล็กน้อยเกี่ยวกับวิธีการใช้ตัวแปร

<xsl:variable name="nl" select="'&#10;'"/>
<xsl:template match="/">
    <xsl:value-of select="$nl" disable-output-escaping="no"/>
    <xsl:apply-templates select="*"/>
</xsl:template>

-4

เพียงเพิ่มแท็กนี้:

<br/>

มันใช้งานได้สำหรับฉัน;)


7
คำถามเกี่ยวกับการส่งข้อความ วิธีแก้ปัญหาของคุณจะใช้ได้ก็ต่อเมื่อแสดงผลเป็น HTML
oberlies
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.