2012-08-29 3 views
0

에서 네 개의 노드는 우선이 질문의 알고 : 나는 인해 요소 구조에 작동하는 것으로 확인하지 않았거나 그냥, 두 가지 중 하나를 모드 사용 실패 그러나 XSLT: Loop selecting two elements at a timeXSLT 루프 - 한 번

.

<input> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
</input> 

나는 다음과 같은 구조를 가지고 XML의 다음 배치 한 : - 동일한 ID의 노드가 항상 함께 그룹화됩니다 - 항상 내가하고자

하나 개의 ID에 네 개의 노드가있을 것입니다 한 번에 하나의 ID로 4 개의 노드를 선택하고 4 개의 각 그룹을 반복 할 수 있으므로 데이터를 하나의 출력 라인으로 조작 할 수 있습니다.

어떻게 접근하는 것이 가장 좋을까요?

답변

1

이 XSLT :

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

<xsl:key name="keyByID" match="node" use="id"/> 

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

<xsl:template match="input"> 
    <xsl:for-each select="node[generate-id()=generate-id(key('keyByID',id)[1])]"> 
     <block> 
      <id> 
       <xsl:value-of select="id"/> 
      </id> 
      <value> 
       <xsl:value-of select="value"/> 
      </value> 
     </block> 
    </xsl:for-each> 
</xsl:template> 


</xsl:stylesheet> 

는 입력 XML에 적용 : 출력은 <id>에 의해 그룹화

<?xml version="1.0" encoding="UTF-8"?> 
<output> 
<block> 
    <id>1</id> 
    <value>3</value> 
</block> 
<block> 
    <id>2</id> 
    <value>4</value> 
</block> 
</output> 

:

<?xml version="1.0" encoding="UTF-8"?> 
<input> 
<node> 
    <id>1</id> 
    <value>3</value> 
</node> 
<node> 
    <id>1</id> 
    <value>3</value> 
</node> 
<node> 
    <id>1</id> 
    <value>3</value> 
</node> 
<node> 
    <id>1</id> 
    <value>3</value> 
</node> 
<node> 
    <id>2</id> 
    <value>4</value> 
</node> 
<node> 
    <id>2</id> 
    <value>4</value> 
</node> 
<node> 
    <id>2</id> 
    <value>4</value> 
</node> 
<node> 
    <id>2</id> 
    <value>4</value> 
</node> 
</input> 

이 그룹화 출력 XML을 제공합니다. 그것은 당신이 찾고있는 것입니까? 나는 잘 모르겠다. 이 Muenchian 그룹화는 구조를 단순화합니다.

안부, 피터

+0

훌륭하게 일한, thankyou. – Mike

0

당신은 다음

<xsl:template match="node[not(preceding-sibling::node[1]/id = id])"> 

각 ID에 대한 노드 (id가 다르다 기술적으로 모든 노드와 일치하는 것과 동일한 ID의 노드가 항상 같은 인접 것이라는 점을 보장 할 수있는 경우 앞에있는 노드가 있으면), 그 템플릿 내에서 following-sibling::을 사용하여 다른 노드를 찾거나 단순히 최상위 레벨에서 키를 정의한 다음이를 사용하여 동일한 ID를 가진 모든 노드를 추출 할 수 있습니다.

1

node 요소는 어떤 그룹화 방법을 사용하지 않는 4, 원하는 출력은 매우 간단한 변환에 의해 생성 될 수있는 그룹에있을 항상을 보장다시피(예 : Muenchian 또는 형제 자매의 비교 등) 그리고 아마도 더 효율적입니다 :

<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="node()|@*" name="identity"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="node"> 
    <sample> 
    <xsl:call-template name="identity"/> 
    </sample> 
</xsl:template> 
<xsl:template match="node[not(position() mod 4 = 1)]"/> 
</xsl:stylesheet> 

이 transfor을 mation의가 제공하는 XML 문서에 적용됩니다

<input> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>1</id> 
    <value>3</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
    <node> 
    <id>2</id> 
    <value>4</value> 
    </node> 
</input> 

원하는 정확한 결과가을 생산 :

<input> 
    <sample> 
     <node> 
     <id>1</id> 
     <value>3</value> 
     </node> 
    </sample> 
    <sample> 
     <node> 
     <id>2</id> 
     <value>4</value> 
     </node> 
    </sample> 
</input> 

설명 :

  1. identity rule 사본 " 있는 그대로 "실행을 위해 선택된 모든 노드에 적용됩니다.

  2. 다른 템플릿은 node 요소마다 ID 템플릿을 덮어 씁니다.이 템플릿의 부모는 4k+1 st node입니다. 이 템플릿은 래퍼 요소 (sample)를 생성 한 다음이라는 ID 템플릿 을 호출하여 출력에 자신을 복사합니다.

  3. 또 다른 템플리트는 node 요소마다 ID 템플리트를 겹쳐 씁니다. 이 템플리트는 모든 node 요소와 일 치하지만 이전 템플리트와 일치하지 않는 노드 (즉, node 요소에 대해 4k+1 st node 상위가 아닌 노드)에 대해서만 실행하도록 선택됩니다 (이전 템플리트보다 선호 됨). 이 템플릿은 보다 작기 때문에 이전 서식 파일보다입니다.

  4. 위의 3.에서 설명한 템플릿에는 본문이 없으므로 일치하는 node 요소를 출력에서 ​​효과적으로 "삭제"합니다.