2012-07-23 132 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我也可以爲他人做到這一點。請告訴我如何正確地做到這一點。

ADDED

<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: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行。 – 2012-07-24 02:51:32

+0

@Dimitre,我用簡單的關卡增加了更多的問題。請看看。 – Setinger 2012-07-26 05:32:33

+0

Setinger,你已經添加了一個示例,請解釋一下是什麼,是你有可能的輸入還是你想要的輸出?如果它是一個可能的輸入,你也需要顯示你想要的輸出。 – 2012-07-26 09:41:26

回答

2

我想你主要是想另一個劃分步驟;樣式表

<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> 

變換校正輸入

<?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> 

到結果

<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> 

那有你貼我覺得結構,與<p name="h-title" other="main">Introduction</p>元素是一節中的例外而您發佈的示例將其移至頂端。我不確定這樣做的規則是什麼,所以我沒有試圖實現這一點。請說明您是否只想將該單一元素移到頂部,而不是將該組應用到該元素,或者是否有更復雜的規則來豁免某些元素。

[編輯]如果你只是想將所有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 2012-07-26 05:26:48

+0

如果我在這裏感到困惑,請看我的新問題。 – Setinger 2012-07-27 18:18:04

相關問題