2011-04-09 4 views
3
<xsl:template match="location"> 
     <xsl:if test="not(preceding::location)"> 
      <table> 
       <tr> 
        <th>Name</th> 
        <th>City</th> 
        <th>State</th> 
        <th>Zip Code</th> 
        <th>Country</th> 
       </tr> 
     </xsl:if> 
     <tr> 
      <td><xsl:value-of select=".//name"/></td> 
      <td><xsl:value-of select=".//city"/></td> 
      <td><xsl:value-of select=".//state"/></td> 
      <td><xsl:value-of select=".//zip"/></td> 
      <td><xsl:value-of select=".//countdy"/></td> 
     </tr> 
     <xsl:if test="not(following::location)"> 
      </table> 
     </xsl:if> 
    </xsl:template> 

XSLT에서 일치하지 않는 태그를 허용하는 방법은 없나요? 아니면 원하는 효과를 얻기위한 다른 방법이 있습니까?일치하지 않는 태그를 허용하는 XSLT?

+0

가능한 복제본 [XSLT : 종료 태그가 아님] (http://stackoverflow.com/questions/2872396/xslt-opening-but-not-closing-tags) –

+0

그리고 http://stackoverflow.com/questions/3701708/how-can-i-print-a-single-div-closing-it-in-xslt 및 http://stackoverflow.com/questions/2202377/xslt-dynamically-start-and- 닫기 태그 및 ... –

답변

5

Dimitre와 마찬가지로 XSLT에서 일치하지 않는 태그를 허용 할 방법이 없습니다. 태그가 일치하지 않아야합니다.

템플릿을 보면 XML 인스턴스의 <location> 요소 중 html 테이블을 만드는 것처럼 보입니다. 처음으로 <location>에서 테이블을 열고 마지막으로 <location>에서 테이블을 닫으려고합니다.

가장 쉬운 방법은 상위 수준 (상위/상위)에서 테이블을 연 다음 <location> 데이터로 테이블을 채우는 것입니다.

<table> 
    <tr> 
     <th>Name</th> 
     <th>City</th> 
     <th>State</th> 
     <th>Zip Code</th> 
     <th>Country</th> 
    </tr> 
    <tr> 
     <td>name 1</td> 
     <td>city 1</td> 
     <td>state 1</td> 
     <td>zip 1</td> 
     <td>country 1</td> 
    </tr> 
    <tr> 
     <td>name 2</td> 
     <td>city 2</td> 
     <td>state 2</td> 
     <td>zip 2</td> 
     <td>country 2</td> 
    </tr> 
    <tr> 
     <td>name 3</td> 
     <td>city 3</td> 
     <td>state 3</td> 
     <td>zip 3</td> 
     <td>country 3</td> 
    </tr> 
</table> 

:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="doc"> 
    <!--The table is inserted here.--> 
    <table> 
     <tr> 
     <th>Name</th> 
     <th>City</th> 
     <th>State</th> 
     <th>Zip Code</th> 
     <th>Country</th> 
     </tr> 
     <!--This is where we apply the templates to populate the rows.--> 
     <xsl:apply-templates select="location"/> 
    </table> 
    </xsl:template> 

    <!--This template populates the row(s).--> 
    <xsl:template match="location"> 
    <tr> 
     <td> 
     <xsl:value-of select="name"/> 
     </td> 
     <td> 
     <xsl:value-of select="city"/> 
     </td> 
     <td> 
     <xsl:value-of select="state"/> 
     </td> 
     <td> 
     <xsl:value-of select="zip"/> 
     </td> 
     <td> 
     <xsl:value-of select="country"/> 
     </td> 
    </tr> 
    </xsl:template> 

</xsl:stylesheet> 

이 출력입니다 : 여기에 테이블을 생성하는 스타일 시트의

<doc> 
    <location> 
    <name>name 1</name> 
    <city>city 1</city> 
    <state>state 1</state> 
    <zip>zip 1</zip> 
    <country>country 1</country> 
    </location> 
    <location> 
    <name>name 2</name> 
    <city>city 2</city> 
    <state>state 2</state> 
    <zip>zip 2</zip> 
    <country>country 2</country> 
    </location> 
    <location> 
    <name>name 3</name> 
    <city>city 3</city> 
    <state>state 3</state> 
    <zip>zip 3</zip> 
    <country>country 3</country> 
    </location> 
</doc> 

: 여기

3 개 <location>의가있는 샘플 XML 파일입니다 어떤 이유로 든에서 <table>을 생성해야하는 경우, 여전히 그렇게 할 수 있습니다. 그것은 더 많은 코드가 필요합니다. - 스타일 시트 요소 노드는 결과 트리 불가분 요소 노드를 작성 불가분 명령이다

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <!--The table is created at the first location and 
    the first row is populated.--> 
    <xsl:template match="location[1]"> 
    <table> 
     <tr> 
     <th>Name</th> 
     <th>City</th> 
     <th>State</th> 
     <th>Zip Code</th> 
     <th>Country</th> 
     </tr> 
     <xsl:call-template name="location-row"/> 
     <!--Here is where we apply the other template to populate the other rows. 
     Notice we use a "mode" to differentiate the template from the generic 
     "location" template.--> 
     <xsl:apply-templates select="following-sibling::location" mode="not-first"/> 
    </table> 
    </xsl:template> 

    <!--This template will output the other rows.--> 
    <xsl:template match="location" mode="not-first" name="location-row"> 
    <tr> 
     <td> 
     <xsl:value-of select="name"/> 
     </td> 
     <td> 
     <xsl:value-of select="city"/> 
     </td> 
     <td> 
     <xsl:value-of select="state"/> 
     </td> 
     <td> 
     <xsl:value-of select="zip"/> 
     </td> 
     <td> 
     <xsl:value-of select="country"/> 
     </td> 
    </tr> 
    </xsl:template> 

    <!--This generic template matches locations other than the first one. 
    Basically it is consuming it so we don't get duplicate output.--> 
    <xsl:template match="location"/> 

</xsl:stylesheet> 
+0

+1 두 가지 올바른 접근법. 첫 번째'location' 규칙의 콘텐츠 템플릿이'not-first' 모드 규칙에'location'의 콘텐츠 템플릿을 복제하고 있다는 것에주의하십시오. 이것은'xsl : call-template' 명령을위한 올바른 장소입니다. –

+0

@Alejandro : 뛰어난 관찰. 이렇게하면 두 번째 예제가 훨씬 단순 해집니다. 나는 3am에 질문에 대답하는 것을 놓친다는 것을 알았다. 다시 한 번 감사드립니다! –

3

는 어떤 방법

없음 XSLT

에 일치하지 않는 태그를 허용하는 것입니다.

XSLT 스타일 시트는 올바른 형식의 XML 문서이어야합니다.

또한 속성 값이 <xsl:output> 인 경우 "xml"로 지정하면 출력은 항상 올바른 형식의 XML 조각 (또는 문서)이됩니다.

... 같은 효과를 얻으려면 다른 방법이 있습니까?

해결하려는 문제를 정의하면 많은 사람들이 잘못된 형식의 XSLT가 필요없는 해결책을 제시 할 수 있습니다.

3

그 XSLT 기억이 트리 구축 :

다음 스타일은 제 스타일과 동일한 출력을 생성 ; 출력에 시작 태그를 쓰는 명령 인 스타일 시트의 시작 태그와 종료 태그를 출력에 쓰는 명령 인 스타일 시트의 끝 태그를 생각해서는 안됩니다.

일반적으로 우리가 이런 종류의 것을 보았을 때 (그리고 우리가 언어로 시작했을 때 그것을 시도해 보았을 때) XML을 텍스트로 쓰는 절차 언어로 그룹화하려는 시도였습니다. XSLT 사고 방식, 특히 XML을 나무로 생각해야합니다.

0

문제의 단순화 된 버전으로 일반적인 문제입니다. (XSLT를 프로 시저 언어로 접근하지 말고 무차별 대입을 사용하여 이전에이를 해결 한 조언에 영감을 받았다.)

기본적으로 HTML 출력을 위해 PRE 태그로 코드 줄을 괄호로 묶고 싶습니다.

<xsl:variable name="new_line" select="'&#xA;'"/> 

<xsl:template match="//text:p[@text:style-name='Code_20_Block_20_Beg']"> 
    <PRE> 
    <xsl:for-each select="//text:p[@text:style-name='Code_20_Block']"> 
<xsl:apply-templates/><xsl:value-of select="$new_line"/> 
    </xsl:for-each> 
    </PRE> 
</xsl:template> 


<xsl:template match="//text:p[@text:style-name='Code_20_Block']"> 
</xsl:template> 

나는 이미를위한 각 루프에 의해 처리 된 'Code_20_Block'라인을 무시 (끝) 빈 템플릿을 사용했다 : 및 코드의 첫 번째 줄은 독특한 스타일을 가지고 있었다. 아마 이것에 대한 더 나은 해결책이있을 것입니다.

관련 문제