2010-02-17 2 views
2

XML을 HTML로 변환 중입니다. XML의 일부에서는 특정 자손을 비교할 때 "동일"하게 보이는 요소를 계산해야하며 다른 자손과 특성은 무시해야합니다.자손의 하위 집합을 기반으로 "동일"요소를 계산하는 XSLT

다음은 XML의 간단한 예입니다. 진짜는 훨씬 더 복잡합니다. 두 혐의가있는 경우 입법, 설명, placeOfOffence 및 dateOfOffence 요소 매치 동일한 고려되어야한다, 각 lodgedComplaint에서

<complaints> 
    <lodgedComplaint> 
     <defendant>First Person</defendant> 
     <charge> 
      <actionNumber>1</actionNumber> 
      <offence> 
       <offenceSection> 
        <legislation>SA1</legislation> 
        <description>Stealing</description> 
       </offenceSection> 
       <placeOfOffence>Sydney</placeOfOffence> 
       <dateOfOffence>2010-01-01</dateOfOffence> 
       <particular>value=20</particular> 
      </offence> 
     </charge> 
     <charge> 
      <actionNumber>2</actionNumber> 
      <offence> 
       <offenceSection> 
        <legislation>SA2</legislation> 
        <description>Theft</description> 
       </offenceSection> 
       <placeOfOffence>Sydney</placeOfOffence> 
       <dateOfOffence>2010-01-01</dateOfOffence> 
      </offence> 
     </charge> 
     <charge> 
      <actionNumber>3</actionNumber> 
      <offence> 
       <offenceSection> 
        <legislation>SA2</legislation> 
        <description>Theft</description> 
       </offenceSection> 
       <placeOfOffence>London</placeOfOffence> 
       <dateOfOffence>2010-01-01</dateOfOffence> 
      </offence> 
     </charge> 
     <charge> 
      <actionNumber>4</actionNumber> 
      <offence> 
       <offenceSection> 
        <legislation>SA1</legislation> 
        <description>Stealing</description> 
       </offenceSection> 
       <placeOfOffence>Sydney</placeOfOffence> 
       <dateOfOffence>2010-01-01</dateOfOffence> 
       <particular>value=50</particular> 
      </offence> 
     </charge> 
     <charge> 
      <actionNumber>5</actionNumber> 
      <offence> 
       <offenceSection> 
        <legislation>SA2</legislation> 
        <description>Theft</description> 
       </offenceSection> 
       <placeOfOffence>Sydney</placeOfOffence> 
       <dateOfOffence>2010-01-02</dateOfOffence> 
      </offence> 
     </charge> 
    </lodgedComplaint> 
    <lodgedComplaint> 
     <defendant>Second Person</defendant> 
     <charge> 
      <actionNumber>1</actionNumber> 
      <offence> 
       <offenceSection> 
        <legislation>SA1</legislation> 
        <description>Stealing</description> 
       </offenceSection> 
       <placeOfOffence>Sydney</placeOfOffence> 
       <dateOfOffence>2010-01-01</dateOfOffence> 
       <particular>value=35</particular> 
      </offence> 
     </charge> 
    </lodgedComplaint> 
</complaints>

: 난 그냥 계산에 관련이없는 요소를 제거했습니다. actionNumber 및 특정 요소는 무시해야합니다 (특정 요소는 선택 사항이며 주어진 스키마에서 제한되지 않습니다).

원하는 출력은 다음과 비슷한 모습이 될 것

First Person 
    2 counts of Stealing at Sydney on 1/1/2010 under SA1 
    1 count of Theft at Sydney on 1/1/2010 under SA2 
    1 count of Theft at London on 1/1/2010 under SA2 
    1 count of Theft at Sydney on 2/1/2010 under SA2 
Second Person 
    1 count of Stealing at Sydney on 1/1/2010 under SA1

여기에 내가 다른 곳에서 스택 오버플로와에 읽은 것들을 기반으로, 시도는 XSLT이다. 작동하지 않습니다. 청구 내역이 전혀 나타나지 않습니다. concat()을 사용하면 문제가 발생한다고 생각합니다. 어떻게해야합니까?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" encoding="UTF-8" indent="yes"/> 
    <xsl:key name="matchOffence" match="offence" use="concat(offenceSection/legislation,offenceSection/description,placeOfOffence,dateOfOffence)"/> 
    <xsl:template match="/"> 
     <html> 
      <head> 
       <title>CRIMES Listings</title> 
       <link rel="stylesheet" type="text/css" href="global_styles.css"/> 
       <link rel="stylesheet" type="text/css" href="styles.css"/> 
      </head> 
      <body> 
       <xsl:apply-templates select="complaints/lodgedComplaint"/> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="lodgedComplaint"> 
     <br/> 
     <xsl:value-of select="defendant"/> 
     <xsl:for-each select="charge/offence[generate-id(concat(offenceSection/legislation,offenceSection/description,placeOfOffence,dateOfOffence))=generate-id(key('matchOffence',.))]"> 
      <br/> 
      <xsl:value-of select="count(../../charge/offence[(offenceSection/legislation=current()/offenceSection/legislation) and (offenceSection/description=current()/offenceSection/description) and (placeOfOffence=current()/placeOfOffence) and (dateOfOffence=current()/dateOfOffence)])"/> 
      counts of <b><xsl:value-of select="offenceSection/description"/></b> 
      at <b><xsl:value-of select="placeOfOffence"/></b> 
      on <b><xsl:call-template name="date"> 
       <xsl:with-param name="text" select="dateOfOffence"/> 
      </xsl:call-template></b> 
      under <b><xsl:value-of select="offenceSection/legislation"/></b> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="date"> 
     <xsl:param name="text" select="."/> 
     <xsl:choose> 
      <xsl:when test="contains($text,'-')"> 
       <xsl:call-template name="date"> 
        <xsl:with-param name="text" select="substring-after($text,'-')"/> 
       </xsl:call-template>/<xsl:value-of select="substring-before($text,'-')"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="$text"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet>

답변

1

는 스타일 시트에 두 가지 문제가 있습니다.

  1. 당신은 문자열의 결과를 생성하는 concat()의 결과를 사용하여 generate-id()에 노력하고 있습니다. generate-id()은 노드에서만 작동합니다. 다른 문제는 <xsl:for-each select="charge/offence[generate-id(.)=generate-id(key('matchOffence',concat(offenceSection/legislation,./offenceSection/description,placeOfOffence,dateOfOffence)))]">

  2. key에 사용되는 문자열 값이 고유되지 않는 것입니다 :

    그것은으로 다시 작성해야합니다. 두 번째 사람의 offence은 첫 번째 사람의 offense 중 하나와 동일한 값을 갖습니다. 이렇게하면 두 번째 사람의 출력이 생성되지 않습니다. 키의 defendant 요소의 값을 추가하여 key을 더 고유하게 만들 수 있습니다.

    key을 조정 한 후, 당신은 분명히 for-each을 조정해야합니다. 스타일 시트에 모두 함께 퍼팅

:

<?xml version="1.0" encoding="UTF-8"?>  
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" encoding="UTF-8" indent="yes"/> 
    <xsl:key name="matchOffence" match="offence" use="concat(../../defendant,offenceSection/legislation,offenceSection/description,placeOfOffence,dateOfOffence)"/> 
    <xsl:template match="/"> 
     <html> 
      <head> 
       <title>CRIMES Listings</title> 
       <link rel="stylesheet" type="text/css" href="global_styles.css"/> 
       <link rel="stylesheet" type="text/css" href="styles.css"/> 
      </head> 
      <body> 
       <xsl:apply-templates select="complaints/lodgedComplaint"/> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="lodgedComplaint"> 
     <br/> 
     <xsl:value-of select="defendant"/> 
     <xsl:for-each select="charge/offence[generate-id(.)=generate-id(key('matchOffence',concat(../../defendant,offenceSection/legislation,./offenceSection/description,placeOfOffence,dateOfOffence)))]"> 

      <br/> 
      <xsl:value-of select="count(../../charge/offence[(offenceSection/legislation=current()/offenceSection/legislation) and (offenceSection/description=current()/offenceSection/description) and (placeOfOffence=current()/placeOfOffence) and (dateOfOffence=current()/dateOfOffence)])"/> 
      counts of <b><xsl:value-of select="offenceSection/description"/></b> 
      at <b><xsl:value-of select="placeOfOffence"/></b> 
      on <b><xsl:call-template name="date"> 
       <xsl:with-param name="text" select="dateOfOffence"/> 
      </xsl:call-template></b> 
      under <b><xsl:value-of select="offenceSection/legislation"/></b> 

     </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="date"> 
     <xsl:param name="text" select="."/> 
     <xsl:choose> 
      <xsl:when test="contains($text,'-')"> 
       <xsl:call-template name="date"> 
        <xsl:with-param name="text" select="substring-after($text,'-')"/> 
       </xsl:call-template>/<xsl:value-of select="substring-before($text,'-')"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="$text"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
+0

덕분에 - 완벽하게 작동합니다. –

관련 문제