2012-07-23 2 views
1

xsl : for-each-group에 문제가있어서 here에서 매우 잘 해결되었습니다. 이제 다른 문제가 생겼어. 나는 이것을 입력으로 가지고있다.XSLT의 특정 노드 두 개 사이에 템플릿 적용

<?xml version="1.0" encoding="UTF-8"?> 

    <body> 
     <p name ="section">this is section</p> 
     <p name="h-title" other="main">Introduction</p> 
     <p name="h1-title " other="other-h1">XSLT and XQuery</p> 
     <p name="h2-title" other=" other-h2">XSLT</p> 
     <p name=""> 
      <p1 name="bold"> XSLT is used to write stylesheets.</p1> 
     </p> 
     <p name="h2-title " name="other-h2">XQuery</p> 
     <p name=""> 
      <p1 name="bold"> XQuery is used to query XML databases.</p1> 
     </p> 
     <p name="h3-title" name="other-h3">XQuery and stylesheets</p> 
     <p name=""> 
      <p1 name="bold"> XQuery is used to query XML databases.</p1> 
     </p> 
     <p name ="section">this is section</p> 
     <p name="h1-title " other="other-h1">XSLT and XQuery</p> 
     <p name="h2-title " other=" other-h2">XSLT</p> 
     <p name ="section">this is section</section> 
     <p name="h1-title " other="other-h1">XSLT and XQuery</p> 
     <p name="h2-title " other=" other-h2">XSLT</p> 
    </body> 

이제 내 원하는 출력 (하지 제대로 작동)이

<?xml version="1.0" encoding="UTF-8"?> 
<body> 
    <p name="h-title " other="main">Introduction</p> 
    <section> 
    <p name ="section">this is section</p> 
    <h1> 
     <p name="h1-title " other="other-h1"> XSLT and XQuery </p> 
     <h2> 
     <p name="h2-title " other="other-h2">XSLT</p> 
     <p name=""> 
      <p1 name="bold">XSLT is used to write stylesheets. 
      </p1> 
     </p> 
     </h2> 
     <h2> 
     <p name="h2-title " other="other-h2"> XQuery is used to query XMLdatabases  
     </p> 
     <p name=""> 
      <p name="bold"> XQuery is used to query XML databases.</p> 
     </p> 
     <h3> 
      <p name="h3-title " name="other-h3">XQuery and stylesheets</p> 
      <p name=""> 
      <p1 name="bold"> XQuery is used to query XML databases.</p1> 
      </p> 
     </h3> 
     </h2> 
</h1> 
</section> 
<section> 
<p name ="section">this is section</p> 
<h1> 
      <p name="h1-title " other="other-h1">XSLT and XQuery</p> 
     <h2> 
      <p name="h2"-title other=" other-h2">XSLT</p> 
     </h2> 
</h1> 
</section> 
<section> 
<p name ="section">this is section</p> 
<h1> 
      <p name="h1-title " other="other-h1">XSLT and XQuery</p> 
     <h2> 
      <p name="h2"-title other=" other-h2">XSLT</p> 
     </h2> 
</h1> 
</section> 
</body> 

내 사용되는 스타일 시트

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xmlns:mf="http://example.com/mf" 
     exclude-result-prefixes="xs mf"> 

    <xsl:param name="prefix" as="xs:string" select="'h'"/> 
    <xsl:param name="suffix" as="xs:string" select="'-title'"/> 

    <xsl:output method="html" version="4.0" indent="yes"/> 

    <xsl:function name="mf:group" as="node()*"> 
     <xsl:param name="items" as="node()*"/> 
     <xsl:param name="level" as="xs:integer"/> 
     <xsl:for-each-group select="$items" group-starting-with="p[@name = concat($prefix,$level, $suffix)]"> 
     <xsl:choose> 
      <xsl:when test="not(self::p[@name = concat($prefix, $level, $suffix)])"> 
      <xsl:apply-templates select="current-group()"/> 
      </xsl:when> 
      <xsl:otherwise> 
      <xsl:element name="h{$level}"> 
       <xsl:apply-templates select="."/> 
       <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/> 
      </xsl:element> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:function> 

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

    <xsl:template match="body" name ="myTemplate"> 
     <xsl:copy> 
     <xsl:sequence select="mf:group(*, 1)"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="body[@name='section']"> 
     <section> 
      <xsl:call-template name="myTemplate"/> 
     </section> 
    </xsl:template>  
    </xsl:stylesheet> 

는하지만이 올바르지 않습니다. <p name ="section">this is section</p>과 같은 것들이 널리 보입니다. 뿐만 아니라이 같은 몇 안되는 사람이 있습니다. 누군가가 section으로 처리하는 방법을 보여 주면 다른 사람들을 위해서도 그렇게 할 수있을 것입니다. 이 작업을 올바르게 수행하는 방법을 알려주십시오.

내가

<xsl:for-each-group select="*" group-starting-with="p[@name = 'intro']"> 
      <intro> 
        <xsl:apply-templates select="current()"/> 
      </intro> 
</xsl:for-each-group> 
+0

가 Setinger : 정말 무엇을 이해할 수 없었다을 변형이해야만합니다. 질문을 수정하고 설명하십시오. 아마 아주 작은 예제만으로도 충분할 것이며, 요구 사항은 구현할 수없는 요구 사항이어야합니다. 다른 모든 요구 사항은 건너 뛰십시오. 간단한 예제 XML 문서는 아마도 단지 10 줄 일 수 있습니다. –

+0

@ Dimitre, 간단한 질문으로 질문에 더 많이 추가했습니다. 저것 좀 봐. – Setinger

+0

Setinger, 샘플을 추가했는지, 그게 뭔지 설명해 주시겠습니까? 아니면 가지고있는 가능한 입력입니까? 그리고 그것이 가능한 입력이라면, 당신은 그것을 위해 원하는 출력을 보여줄 필요가있을 것입니다. –

답변

2

난 당신이 주로 다른 그룹화 단계를 원한다고 생각했던 것

<body> 
<intro> 
<p></p> 
<p></p> 
</intro> 

<section> 
<para> 
</para> 
<h1></h2> 
<h2></h2> 
</section> 

<section> 
<para> 
</para> 
<h1></h2> 
<h2></h2> 
</section> 

<sumary> 
</summary> 
</body> 

추가; 스타일 시트

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:mf="http://example.com/mf" 
    exclude-result-prefixes="xs mf"> 

<xsl:param name="prefix" as="xs:string" select="'h'"/> 
<xsl:param name="suffix" as="xs:string" select="'-title'"/> 

<xsl:output method="html" version="4.0" indent="yes"/> 

<xsl:function name="mf:group" as="node()*"> 
    <xsl:param name="items" as="node()*"/> 
    <xsl:param name="level" as="xs:integer"/> 
    <xsl:for-each-group select="$items" group-starting-with="p[@name = concat($prefix, $level, $suffix)]"> 
    <xsl:choose> 
     <xsl:when test="not(self::p[@name = concat($prefix, $level, $suffix)])"> 
     <xsl:apply-templates select="current-group()"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:element name="h{$level}"> 
      <xsl:apply-templates select="."/> 
      <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/> 
     </xsl:element> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:for-each-group> 
</xsl:function> 

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

<xsl:template match="body"> 
    <xsl:copy> 
    <xsl:for-each-group select="*" group-starting-with="p[@name = 'section']"> 
     <section> 
     <xsl:sequence select="mf:group(current-group(), 1)"/> 
     </section> 
    </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

는 부 내부 인 <p name="h-title" other="main">Introduction</p> 요소를 제외하고, 그 결과는 I 생각 게시 한 구조를 갖는다

<body> 
    <section> 
     <p name="section">this is section</p> 
     <p name="h-title" other="main">Introduction</p> 
     <h1> 
     <p name="h1-title" other="other-h1">XSLT and XQuery</p> 
     <h2> 
      <p name="h2-title" other=" other-h2">XSLT</p> 
      <p name=""> 

       <p1 name="bold"> XSLT is used to write stylesheets.</p1> 

      </p> 
     </h2> 
     <h2> 
      <p name="h2-title" other="other-h2">XQuery</p> 
      <p name=""> 

       <p1 name="bold"> XQuery is used to query XML databases.</p1> 

      </p> 
      <h3> 
       <p name="h3-title" other="other-h3">XQuery and stylesheets</p> 
       <p name=""> 

        <p1 name="bold"> XQuery is used to query XML databases.</p1> 

       </p> 
      </h3> 
     </h2> 
     </h1> 
    </section> 
    <section> 
     <p name="section">this is section</p> 
     <h1> 
     <p name="h1-title" other="other-h1">XSLT and XQuery</p> 
     <h2> 
      <p name="h2-title" other=" other-h2">XSLT</p> 
     </h2> 
     </h1> 
    </section> 
    <section> 
     <p name="section">this is section</p> 
     <h1> 
     <p name="h1-title" other="other-h1">XSLT and XQuery</p> 
     <h2> 
      <p name="h2-title" other=" other-h2">XSLT</p> 
     </h2> 
     </h1> 
    </section> 
</body> 

에 보정 입력

<?xml version="1.0" encoding="UTF-8"?> 

    <body> 
     <p name ="section">this is section</p> 
     <p name="h-title" other="main">Introduction</p> 
     <p name="h1-title" other="other-h1">XSLT and XQuery</p> 
     <p name="h2-title" other=" other-h2">XSLT</p> 
     <p name=""> 
      <p1 name="bold"> XSLT is used to write stylesheets.</p1> 
     </p> 
     <p name="h2-title" other="other-h2">XQuery</p> 
     <p name=""> 
      <p1 name="bold"> XQuery is used to query XML databases.</p1> 
     </p> 
     <p name="h3-title" other="other-h3">XQuery and stylesheets</p> 
     <p name=""> 
      <p1 name="bold"> XQuery is used to query XML databases.</p1> 
     </p> 
     <p name ="section">this is section</p> 
     <p name="h1-title" other="other-h1">XSLT and XQuery</p> 
     <p name="h2-title" other=" other-h2">XSLT</p> 
     <p name ="section">this is section</p> 
     <p name="h1-title" other="other-h1">XSLT and XQuery</p> 
     <p name="h2-title" other=" other-h2">XSLT</p> 
    </body> 

변환 게시 된 예제에서는 맨 위로 이동했습니다. 그렇게하기위한 규칙이 무엇인지 잘 모르겠습니다. 따라서 구현하지 않으려 고합니다. 해당 단일 요소를 맨 위로 이동하고 그룹화를 적용하지 않거나 특정 요소를 제외하는 더 복잡한 규칙이 있는지 여부를 명확히하십시오.

경우 [편집] 당신은 단순히 다음 위의 스타일 시트의 다음 적응이 일해야 정상이 아닌 그룹에 대한 모든 p[@name = 't-title']를 이동할 :

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:mf="http://example.com/mf" 
    exclude-result-prefixes="xs mf"> 

<xsl:param name="prefix" as="xs:string" select="'h'"/> 
<xsl:param name="suffix" as="xs:string" select="'-title'"/> 

<xsl:output method="html" version="4.0" indent="yes"/> 

<xsl:function name="mf:group" as="node()*"> 
    <xsl:param name="items" as="node()*"/> 
    <xsl:param name="level" as="xs:integer"/> 
    <xsl:for-each-group select="$items" group-starting-with="p[@name = concat($prefix, $level, $suffix)]"> 
    <xsl:choose> 
     <xsl:when test="not(self::p[@name = concat($prefix, $level, $suffix)])"> 
     <xsl:apply-templates select="current-group()"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:element name="h{$level}"> 
      <xsl:apply-templates select="."/> 
      <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/> 
     </xsl:element> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:for-each-group> 
</xsl:function> 

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

<xsl:template match="body"> 
    <xsl:copy> 
    <xsl:apply-templates select="p[@name = 'h-title']"/> 
    <xsl:for-each-group select="* except p[@name = 'h-title']" group-starting-with="p[@name = 'section']"> 
     <section> 
     <xsl:sequence select="mf:group(current-group(), 1)"/> 
     </section> 
    </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

Martin 대단히 감사합니다. 이것은 정말 대단합니다. 이것은 제가 제시 한 예와 잘 맞습니다. 그러나 더 많은 레벨을 가지고있을 때 말했듯이, 그것은 어렵습니다. 나는 예제 레벨을 질문에 추가했으며, 내가 그렇게하려고 노력했다. 하지만 정확하지 않습니다. 내가해야 할 일을 말해 줄 수 있니? – Setinger

+0

여기에 혼란 스러울 경우 제 새로운 질문을 참조하십시오. – Setinger