IT story

XSLT에서 새로운 라인 생성

hot-time 2020. 5. 14. 08:01
반응형

XSLT에서 새로운 라인 생성


XSLT에서 텍스트 출력을위한 줄 바꿈을 만들고 싶습니다. 어떤 아이디어?


다음 XSL 코드는 줄 바꿈 문자 를 생성합니다 .

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

A의 캐리지 리턴 , 사용 :

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

이 작업을 위해 내가 선호하는 방법은 다음과 같습니다.

<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)" />

XML 입력에서 SQL을 출력 할 때이 기술을 사용했습니다. 실제로 쉼표, 따옴표 및 줄 바꿈에 대한 변수를 만드는 경향이 있습니다.


xsl : output 태그에 Method = "text"속성을 포함하고 적절한 지점에서 XSL의 리터럴 컨텐츠에 개행을 포함하십시오. XSL의 소스 코드를 깔끔하게 유지하려면 &#10;새 줄을 원하는 엔티티를 사용하십시오 .


당신이 사용할 수있는: <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>

이 변수는 다음과 같이 줄 바꾸기 파일을 생성합니다.

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

@Florjon이 준 것보다 더 많은 정보가 필요하지 않습니다. 어쩌면 우리에게 왜 효과가 없는지 이해하기 위해 작은 세부 사항이 남아있을 수 있습니다.

우선, 내부의 &#xa(16 진수) 또는 &#10(12 진수) <xsl:text/>가 항상 작동하지만 보이지 않을 수도 있습니다.

  1. HTML 마크 업에는 줄 바꿈이 없습니다. 간단한 <br/>것을 사용하면 잘됩니다. 그렇지 않으면 공백이 나타납니다. 브라우저에서 소스를 보면 실제로 무슨 일이 있었는지 알려줍니다. 그러나 특히 소비자가 브라우저가 아닌 경우이 동작이 예상되는 경우가 있습니다. 예를 들어, HTML 페이지를 작성하고 브라우저에 제공하기 전에 빈 줄과 ID로 형식이 지정된 구조를 보려고합니다.
  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>

and that will be ok. Both cr and lf are properly rendered.

  1. Don't forget we're talking about nl, not crlf (nl=lf). My first attempt was to use only cr:&#xd and while the output xml was validated by DOM properly.

I was viewing a corrupted xml:

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

DOM parser disregarded control characters but the rendered didn't. I spent quite some time bumping my head before I realised how silly I was not seeing this!

For the record, I do use a variable inside the body with both CRLF just to be 100% sure it will work everywhere.


I added the DOCTYPE directive you see here:

<?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">

This allows me to use &nl; instead of &#xa; to produce a newline in the output. Like other solutions, this is typically placed inside a <xsl:text> tag.


I have found a difference between literal newlines in <xsl:text> and literal newlines using &#xA;.

While literal newlines worked fine in my environment (using both Saxon and the default Java XSLT processor) my code failed when it was executed by another group running in a .NET environment.

Changing to entities (&#xA;) got my file generation code running consistently on both Java and .NET.

Also, literal newlines are vulnerable to being reformatted by IDEs and can inadvertently get lost when the file is maintained by someone 'not in the know'.


I've noticed from my experience that producing a new line INSIDE a <xsl:variable> clause doesn't work. I was trying to do something like:

<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>

Anything I tried to put in that "new line" (the empty <xsl:text> node) just didn't work (including most of the simpler suggestions in this page), not to mention the fact that HTML just won't work there, so eventually I had to split it to 2 variables, call them outside the <xsl:variable> scope and put a simple <br/> between them, i.e:

<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>

Yeah, I know, it's not the most sophisticated solution but it works, just sharing my frustration experience with XSLs ;)


You can try,

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

It will work.


I second Nic Gibson's method, this was always my favorite:

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

However I have been using the Ant task <echoxml> to create stylesheets and run them against files. The task will do attribute value templates, e.g. ${DSTAMP} , but is also will reformat your xml, so in some cases, the entity reference is preferable.

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

I couldn't just use the <xsl:text>&#xa;</xsl:text> approach because if I format the XML file using XSLT the entity will disappear. So I had to use a slightly more round about approach using variables

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

just add this tag:

<br/>

it works for me ;) .

참고URL : https://stackoverflow.com/questions/723226/producing-a-new-line-in-xslt

반응형