2013-04-12 2 views
1

나는 다음과 같은 XML이 :XSLT 정렬

<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes" media-type="text/html"/> 

     <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
     </xsl:template> 

     <xsl:template match="nodeLevel1"> 
      <xsl:copy> 
      <xsl:apply-templates select="node()|@*"> 
       <xsl:sort select="rank" data-type="number" /> 
      </xsl:apply-templates> 
      </xsl:copy> 
     </xsl:template> 

     </xsl:stylesheet> 

결과는 다음과 같습니다 :

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <nodeLevel1> 
    <nodeType1>node type 1</nodeType1> 
    <nodeType3>node type 3</nodeType3> 
    <nodeType2> 
     <rank>1</rank> 
    </nodeType2> 
    <nodeType2> 
     <rank>2</rank> 
    </nodeType2> 
    <nodeType2> 
     <rank>3</rank> 
    </nodeType2> 
    <nodeType2> 
     <rank>4</rank> 
    </nodeType2> 
</nodeLevel1> 
</root> 

문제

<root> 
    <nodeLevel1> 
    <nodeType1>node type 1</nodeType1> 
    <nodeType2><rank>3</rank></nodeType2> 
    <nodeType2><rank>1</rank></nodeType2> 
    <nodeType2><rank>4</rank></nodeType2> 
    <nodeType2><rank>2</rank></nodeType2> 
    <nodeType3>node type 3</nodeType3> 
    </nodeLevel1> 
</root> 

나는 다음과 같은 XSLT를 사용하여이 XML을 정렬 모든 "nodeType2"가 XML의 올바른 위치에 있지 않다는 것입니다. "nodeType2"앞에 노드 "nodeType1"을 유지하고 "nodeType2"다음에 노드 "nodeType3"을 유지하려면 어떻게해야합니까?

그래서, 결과는 수 갈까요 (그것이 무엇이든로 이름이 변경 될 수 있기 때문에이 솔루션은 "nodeType1"또는 "nodeType3"요소 이름을 사용해서는 안) :

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <nodeLevel1> 
    <nodeType1>node type 1</nodeType1> 
    <nodeType2> 
     <rank>1</rank> 
    </nodeType2> 
    <nodeType2> 
     <rank>2</rank> 
    </nodeType2> 
    <nodeType2> 
     <rank>3</rank> 
    </nodeType2> 
    <nodeType2> 
     <rank>4</rank> 
    </nodeType2> 
    <nodeType3>node type 3</nodeType3> 
</nodeLevel1> 
</root> 

감사를 도와. 이 작업을 수행하는

답변

0

한 가지 방법은 요소

<xsl:template match="nodeType2[1]"> 

그리고이 내

, 당신이 선택하고 종류의 모든 nodeType2 요소 첫 번째 nodeType2 일치하는 템플릿을 가지고있다

<xsl:for-each select="self::*|following-sibling::nodeType2"> 
    <xsl:sort select="rank" data-type="number" /> 
    <!-- Copy element --> 
    <xsl:call-template name="identity" /> 
</xsl:for-each> 

유일한 다른 필요한 것은 다른 템플릿을 멈추는 또 다른 템플릿입니다. nodeType2 요소가 두 번 출력됩니다.

여기
<xsl:template match="nodeType2" /> 

이 XML에 적용되는 전체 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes" media-type="text/html"/> 

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

     <xsl:template match="nodeType2[1]"> 
      <xsl:for-each select="self::*|following-sibling::nodeType2"> 
       <xsl:sort select="rank" data-type="number" /> 
       <xsl:call-template name="identity" /> 
      </xsl:for-each> 
     </xsl:template> 

     <xsl:template match="nodeType2" /> 
</xsl:stylesheet> 

이며, 다음이 변환이 모든 요소 이름과 함께 작동 (이름이 하드 코딩되지 않음)이며 출력

<root> 
    <nodeLevel1> 
     <nodeType1>node type 1</nodeType1> 
     <nodeType2> 
     <rank>1</rank> 
     </nodeType2> 
     <nodeType2> 
     <rank>2</rank> 
     </nodeType2> 
     <nodeType2> 
     <rank>3</rank> 
     </nodeType2> 
     <nodeType2> 
     <rank>4</rank> 
     </nodeType2> 
     <nodeType3>node type 3</nodeType3> 
    </nodeLevel1> 
</root> 
0

입니다 그룹을 식별하기 위해 키를 사용하므로 효율적입니다. :

<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:key name="kSameNamed" match="nodeLevel1/*" use= 
    "generate-id(preceding-sibling::*[not(name()=name(current()))][1])"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="nodeLevel1"> 
    <nodeLevel1> 
    <xsl:apply-templates select= 
    "*[not(name() = name(preceding-sibling::*[1]))]"/> 
    </nodeLevel1> 
</xsl:template> 

<xsl:template match="nodeLevel1/*"> 
    <xsl:for-each select="key('kSameNamed', generate-id(preceding-sibling::*[1]))"> 
    <xsl:sort select="rank" data-type="number"/> 
    <xsl:copy-of select="."/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
,

제공되는 XML 문서에 적용 : 원하는 정확한 결과가 생성됩니다

<root> 
    <nodeLevel1> 
    <nodeType1>node type 1</nodeType1> 
    <nodeType2><rank>3</rank></nodeType2> 
    <nodeType2><rank>1</rank></nodeType2> 
    <nodeType2><rank>4</rank></nodeType2> 
    <nodeType2><rank>2</rank></nodeType2> 
    <nodeType3>node type 3</nodeType3> 
    </nodeLevel1> 
</root> 

:

<root> 
    <nodeLevel1> 
     <nodeType1>node type 1</nodeType1> 
     <nodeType2> 
     <rank>1</rank> 
     </nodeType2> 
     <nodeType2> 
     <rank>2</rank> 
     </nodeType2> 
     <nodeType2> 
     <rank>3</rank> 
     </nodeType2> 
     <nodeType2> 
     <rank>4</rank> 
     </nodeType2> 
     <nodeType3>node type 3</nodeType3> 
    </nodeLevel1> 
</root> 

우리는 지금 완전히 다른 XML 문서에 동일한 변환을 적용하는 경우 :

<r> 
    <nodeLevel1> 
    <X1>node type 1</X1> 
    <Y2><rank>3</rank></Y2> 
    <Y2><rank>1</rank></Y2> 
    <Y2><rank>4</rank></Y2> 
    <Y2><rank>2</rank></Y2> 
    <Z3>node type 3</Z3> 
    <A4><rank>8</rank></A4> 
    <A4><rank>2</rank></A4> 
    <A4><rank>9</rank></A4> 
    <A4><rank>3</rank></A4> 
    <B5><rank>8</rank></B5> 
    <B5><rank>2</rank></B5> 
    <B5><rank>9</rank></B5> 
    <B5><rank>3</rank></B5> 
    <C7>Node of Type C7</C7> 
    </nodeLevel1> 
</r> 

<r> 
    <nodeLevel1> 
     <X1>node type 1</X1> 
     <Y2> 
     <rank>1</rank> 
     </Y2> 
     <Y2> 
     <rank>2</rank> 
     </Y2> 
     <Y2> 
     <rank>3</rank> 
     </Y2> 
     <Y2> 
     <rank>4</rank> 
     </Y2> 
     <Z3>node type 3</Z3> 
     <A4> 
     <rank>2</rank> 
     </A4> 
     <A4> 
     <rank>3</rank> 
     </A4> 
     <A4> 
     <rank>8</rank> 
     </A4> 
     <A4> 
     <rank>9</rank> 
     </A4> 
     <B5> 
     <rank>2</rank> 
     </B5> 
     <B5> 
     <rank>3</rank> 
     </B5> 
     <B5> 
     <rank>8</rank> 
     </B5> 
     <B5> 
     <rank>9</rank> 
     </B5> 
     <C7>Node of Type C7</C7> 
    </nodeLevel1> 
</r> 
:

우리는 다시 정확한 결과를 얻을 수