2014-12-12 7 views
1

문제는 여러 측면이 있습니다태그의 목록을 분리하고 다른

  1. 방법은 태그의 특정 공간이 분리 된 내용을 기준으로 분류 할 수
  2. 방법 부족을 분류하는
  3. 그러한 특정 내용의

    : I의 모습 출력을 생성 할

    <xsl:param name="pKnownTags"> 
        <t>A</t> 
        <t>B</t> 
    </xsl:param> 
    

    말, 태그 알려 주어지면

    <messages> 
        <m> 
        <subject>message tagged with A B C</subject> 
        <tags>A B C</tags> 
        </m> 
    
        <m> 
        <subject>message tagged with B C D</subject> 
        <tags>B C D</tags> 
        </m> 
    
        <m> 
        <subject>message tagged with X Y A</subject> 
        <tags>X Y A</tags> 
        </m> 
    
        <m> 
        <subject>message tagged with C X</subject> 
        <tags>C X</tags> 
        </m> 
    
        <m> 
        <subject>message tagged with Y</subject> 
        <tags>Y</tags> 
        </m> 
    
    </messages> 
    

    :

는 예를 들어, 다음과 같은 데이터를 가지고

Messages tagged with A: 
* message tagged with A B C 
* message tagged with X Y A 

Messages tagged with B: 
* message tagged with A B C 
* message tagged with B C D 

Messages tagged with neither: 
* message tagged with C X 
* message tagged with Y 

EXSLT를 사용하는 것이 좋지만 그렇지 않으면 1.0 솔루션이 필요합니다. . 이것이 가능한가?

답변

0

너무 화려하지 않아도됩니다. 시도 아래를주십시오 : 샘플 입력에서 실행

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl" 
> 
    <xsl:output method="text" indent="yes"/> 

    <xsl:param name="pKnownTags"> 
    <t>A</t> 
    <t>B</t> 
    </xsl:param> 
    <xsl:variable name="pKnownTagsNodeSet" select="exsl:node-set($pKnownTags)/t" /> 

    <xsl:template match="/messages"> 
    <xsl:apply-templates select="$pKnownTagsNodeSet"> 
     <xsl:with-param name="docEl" select="." /> 
    </xsl:apply-templates> 

    <xsl:text>Messages tagged with none of the above:&#xA;</xsl:text> 
    <xsl:apply-templates select="m" mode="checkAbsence" /> 
    </xsl:template> 

    <xsl:template match="t"> 
    <xsl:param name="docEl" select="/.." /> 

    <xsl:value-of select="concat('Messages tagged with ', ., ':&#xA;')"/> 
    <xsl:apply-templates select="$docEl/m[contains(concat(' ', tags, ' '), 
                concat(' ', current(), ' '))]" /> 
    <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

    <xsl:template match="m" mode="checkAbsence"> 
    <xsl:variable name="currentTagsPadded" select="concat(' ', tags, ' ')" /> 
    <xsl:apply-templates 
      select="(.)[not($pKnownTagsNodeSet[contains($currentTagsPadded, 
                 concat(' ', ., ' '))] 
         ) 
        ]" /> 
    </xsl:template> 

    <xsl:template match="m"> 
    <xsl:value-of select="concat('* ', subject, '&#xA;')"/> 
    </xsl:template> 

</xsl:stylesheet> 

, 이것은 생산 :

Messages tagged with A: 
* message tagged with A B C 
* message tagged with X Y A 

Messages tagged with B: 
* message tagged with A B C 
* message tagged with B C D 

Messages tagged with none of the above: 
* message tagged with C X 
* message tagged with Y 
+0

굉장! 후속 조치 몇 가지 : "docEl"선택의 마법은 무엇입니까? 특히, 나는 그것을 단지 "/ messages"(매개 변수로 제거하고 단지 docEl을 사용 했음)로 대체하려고 시도했지만 작동하지 않습니다. 왜 그런가요? – sly

+0

첫째,'select = "/ .."'는 여기서는 아무런 도움이되지 않습니다. 그것은 노드 집합 매개 변수에 사용하는 안전 장치 일뿐입니다. '$ docEl'을 매개 변수로 전달해야하는 이유는 ''요소가 입력 XML과 다른 XML 문서에 존재하기 때문입니다. 't' 요소에 비해'/ message'를 평가하면 아무 것도 찾을 수 없습니다. – JLRishe

+0

감사! 또 다른 질문은 : contains (tags, current())와 같이 contains (...)를 바꾼 것, 즉 concat()을 제거했다는 것입니다. 그것은 같은 출력을 렌더링하는 것 같습니다. 어떤 조건에서 그러한 연결이 필요합니까? (나는이 겉으로보기에 초과 된 concat()을 다른 장소에서 보았고, 그래서 나는 더 믿을만한 패턴이라고 생각합니다. 그렇다면, 왜?) – sly

0

사용 EXSLT는

글쎄, 당신의 프로세서가 지원 경우 괜찮습니다 EXSLT str : tokenize() 함수를 사용하면 매우 간단 할 수 있습니다.

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common" 
xmlns:str="http://exslt.org/strings" 
extension-element-prefixes="exsl str"> 
<xsl:output method="text" encoding="UTF-8"/> 

<xsl:param name="pKnownTags"> 
    <t>A</t> 
    <t>B</t> 
</xsl:param> 

<xsl:variable name="tags-set" select="exsl:node-set($pKnownTags)/t" /> 
<xsl:variable name="xml" select="/" /> 

<xsl:key name="message-by-tags" match="m" use="str:tokenize(tags)" /> 

<xsl:template match="/"> 
    <!-- matching messages --> 
    <xsl:for-each select="$tags-set"> 
     <xsl:variable name="tag" select="." /> 
     <xsl:value-of select="concat('Messages tagged with ', $tag, ':&#10;')"/> 
     <!-- switch context to source document in order to use key --> 
     <xsl:for-each select="$xml"> 
      <xsl:for-each select="key('message-by-tags', $tag)"> 
       <xsl:value-of select="concat('* ', subject, ':&#10;')"/> 
      </xsl:for-each> 
     </xsl:for-each> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:for-each> 

    <!-- non-matching messages --> 
    <xsl:text>Messages tagged with none:&#10;</xsl:text> 
    <xsl:for-each select="messages/m[not(str:tokenize(tags)=$tags-set)]"> 
     <xsl:value-of select="concat('* ', subject)"/> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet>