Programing

XSLT가 기본적으로 모든 텍스트를 출력하는 이유는 무엇입니까?

lottogame 2020. 10. 29. 07:46
반응형

XSLT가 기본적으로 모든 텍스트를 출력하는 이유는 무엇입니까?


안녕하세요, null이면 태그를 삭제하는 변환을 수행했습니다.

내 변환이 제대로 작동하는지 확인하고 싶었으므로 수동으로 확인하는 대신 OUTPUT XML에서 특정 태그의 존재를 확인하는 XSLT 코드를 하나 더 작성했습니다. null이면 두 번째 XSLT는 텍스트 "FOUND". (실제로 XML 종류의 출력이 필요하지는 않지만 검색을 위해 XSLT를 사용하고 있습니다.)

이 XSL 코드로 시도했을 때 ::

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
      FOUND
  </xsl:template>
</xsl:stylesheet>

XML 파일에있는 모든 TEXT DATA를 출력합니다.

이를 피하기 위해 다음 코드를 작성해야했습니다.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
      FOUND
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

이전 코드가 TEXT를 출력하는 이유는 무엇입니까? 다른 모든 텍스트를 무시하도록 XSL을 주장해야하는 이유는 무엇입니까? 모든 XML 파서의 동작 또는 내 자신의 동작입니다 (msxml 파서를 사용하고 있습니다).


이전 코드에서 TEXT를 출력하는 이유는 무엇입니까? 다른 모든 텍스트를 무시하도록 XSL을 주장해야하는 이유는 무엇입니까? 모든 XML 파서의 동작 또는 내 자신의

사양에 지정된 가장 기본적인 XSLT 기능 중 하나 인 XSLT의 기본 제공 템플릿을 발견하고 있습니다.

에서 스펙 :

스타일 시트의 명시 적 템플릿 규칙에 의한 성공적인 패턴 일치가없는 경우 반복 처리를 계속할 수 있도록 기본 제공 템플릿 규칙이 있습니다. 이 템플릿 규칙은 요소 노드와 루트 노드 모두에 적용됩니다. 다음은 기본 제공 템플릿 규칙에 해당하는 내용을 보여줍니다.

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

또한 각 모드에 대한 기본 제공 템플릿 규칙이있어 스타일 시트의 명시 적 템플릿 규칙에 의한 성공적인 패턴 일치가없는 경우 동일한 모드에서 반복 처리를 계속할 수 있습니다. 이 템플릿 규칙은 요소 노드와 루트 노드 모두에 적용됩니다. 다음은 모드 m에 대한 기본 제공 템플릿 규칙에 해당하는 내용을 보여줍니다.

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

다음을 통해 텍스트를 복사하는 텍스트 및 속성 노드에 대한 기본 제공 템플릿 규칙도 있습니다.

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

지침 및 주석 처리를위한 기본 제공 템플릿 규칙은 아무것도하지 않는 것입니다.

<xsl:template match="processing-instruction()|comment()"/>

네임 스페이스 노드에 대한 기본 제공 템플릿 규칙은 아무것도하지 않는 것입니다. 네임 스페이스 노드와 일치 할 수있는 패턴이 없습니다. 따라서 기본 제공 템플릿 규칙은 네임 스페이스 노드에 적용되는 유일한 템플릿 규칙입니다.

기본 제공 템플릿 규칙은 스타일 시트 이전에 암시 적으로 가져온 것처럼 처리되므로 다른 모든 템플릿 규칙보다 가져 오기 우선 순위가 낮습니다. 따라서 작성자는 명시 적 템플릿 규칙을 포함하여 기본 제공 템플릿 규칙을 재정의 할 수 있습니다.

따라서보고 된 동작은 기본 제공 템플릿을 적용한 결과입니다. 세 가지 모두의 첫 번째와 두 번째 템플릿입니다.

프로그래머가 자신의 변환이 "누수"임을 즉시 알 수 있도록 호출 될 때마다 오류 메시지를 발행하는 내장 템플릿 을 자신의 것으로 재정의하는 것은 좋은 XSLT 디자인 패턴 입니다.

예를 들어이 XML 문서가있는 경우 :

<a>
  <b>
    <c>Don't want to see this</c>
  </b>
</a>

이 변환으로 처리됩니다 .

<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="a|b">
   <xsl:copy>
      <xsl:attribute name="name">
        <xsl:value-of select="name()"/>
      </xsl:attribute>
      <xsl:apply-templates/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

결과는 다음과 같습니다.

<a name="a">
   <b name="b">Don't want to see this</b>
</a>

and the programmer will be greatly confused how the unwanted text appeared.

However, just adding this catch-all template helps avoid any such confusion and catch errors immediately:

 <xsl:template match="*">
  <xsl:message terminate="no">
   WARNING: Unmatched element: <xsl:value-of select="name()"/>
  </xsl:message>

  <xsl:apply-templates/>
 </xsl:template>

Now, besides the confusing output the programmer gets a warning that explains the problem immediately:

 WARNING: Unmatched element: c

Later Addition by Michael Kay for XSLT 3.0

In XSLT 3.0, rather than adding a catch-all template rule, you can specify the fallback behaviour on an xsl:mode declaration. For example, <xsl:mode on-no-match="shallow-skip"/> causes all nodes that are not matched (including text nodes) to be skipped, while <xsl:mode on-no-match="fail"/> treats a no-match as an error, and <xsl:mode warning-on-no-match="true"/> results in a warning.


There are several built in template rules in XSL, one of which is this:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

It outputs text.

참고URL : https://stackoverflow.com/questions/3360017/why-does-xslt-output-all-text-by-default

반응형