0

必要なxml要素をブロックで取得しますが、同時に、他のxml要素をキャッチするためのブロックも配置します.しかし、それは私にとってはうまくいきません...

これは XML ドキュメントです

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
    <w:p>
        <w:pPr>
        </w:pPr>
        <w:r>
            <w:t>Text1-</w:t>
        </w:r>  
    </w:p>

    <w:p>
        <w:pPr>
            <w:pStyle w:val="Heading1" /> 
        </w:pPr>
        <w:r>
            <w:t>Text2-</w:t>
        </w:r>  
    </w:p>

    <w:p>
        <w:pPr>
        </w:pPr>
        <w:r>
            <w:t>Text3-</w:t>
        </w:r>  
    </w:p>

    <w:p>
        <w:pPr>
        </w:pPr>
        <w:r>
            <w:t>Text4-</w:t>
        </w:r>  
    </w:p>

    <w:p>
        <w:pPr>
            <w:pStyle w:val="Heading1" /> 
        </w:pPr>
        <w:r>
            <w:t>Text5-</w:t>
        </w:r>  
    </w:p>

</w:body>
</w:document>

これは XSLT ファイルです

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
 exclude-result-prefixes="w">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <Document>

      <xsl:variable name="headingName" select="(//w:body/w:p/w:pPr/w:pStyle[starts-with(@w:val, 'Heading')])[1]/@w:val"/>
      <xsl:variable name="topLevelHeadings" select = "//w:body/w:p[w:pPr/w:pStyle/@w:val = $headingName]"/>

      <xsl:choose>

        <xsl:when test="$topLevelHeadings">
          <Heading>
          <xsl:apply-templates select="$topLevelHeadings">
          </xsl:apply-templates>
          </Heading>
        </xsl:when>

        <xsl:otherwise>
             <xsl:apply-templates select="w:p">
             </xsl:apply-templates>
        </xsl:otherwise>

      </xsl:choose>   

    </Document>
  </xsl:template>  

  <xsl:template match="w:p">
    <Paragraph>
      <xsl:apply-templates />
    </Paragraph>
  </xsl:template>

  <xsl:template match="w:r/w:t">
    <xsl:value-of select="." />
  </xsl:template>

</xsl:stylesheet>

私の生成された出力は次のとおりです。

<Document>
  <Heading>
  <Paragraph>Text2-</Paragraph> 
  <Paragraph>Text5-</Paragraph> 
  </Heading>
</Document>

しかし、私の必要な出力は次のとおりです。

<Document>
      <Paragraph>Text1-</Paragraph> 
      <Heading>
           <Paragraph>Text2-</Paragraph> 
      </Heading>
      <Paragraph>Text3-</Paragraph> 
      <Paragraph>Text4-</Paragraph> 
      <Heading>
           <Paragraph>Text5-</Paragraph> 
      </Heading>
</Document>

Block に問題があると思います。だから、この問題から抜け出すために私を導いてください...

4

2 に答える 2

2

ここでのxsl:chooseの問題は、一度しか使用されず、見出しを持つw:p要素が少なくとも 1 つあるかどうかのみをチェックしていることです。したがって、 Heading要素の出力は 1 つだけになります。xsl:chooseを機能させるには、 w:pテンプレート内で使用する必要があります

<xsl:template match="w:p">
   <xsl:choose>
      <xsl:when test="w:pPr/w:pStyle[starts-with(@w:val, 'Heading')]">
         <Heading>
            <Paragraph>
               <xsl:apply-templates/>
            </Paragraph>
         </Heading>
      </xsl:when>
      <xsl:otherwise>
         <Paragraph>
            <xsl:apply-templates/>
         </Paragraph>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

ただし、ここでxsl:choose を実際に使用する必要はありません。おそらく、一致するw:pPr要素を持つw:p要素に一致する特定のテンプレートを用意するだけで逃げることができます

<xsl:template match="w:p[w:pPr/w:pStyle[starts-with(@w:val, 'Heading')]]">

このテンプレートでは、 Heading要素を出力できます。次に、他のすべてのw:p要素に一致する別のテンプレートを作成して段落を出力します。名前を付ければ、前のテンプレートから呼び出してコードを共有することもできます。

<xsl:template match="w:p" name="para"> 

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" exclude-result-prefixes="w">
   <xsl:output method="xml" indent="yes"/>

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

   <xsl:template match="w:p[w:pPr/w:pStyle[starts-with(@w:val, 'Heading')]]">
      <Heading>
         <xsl:call-template name="para"/>
      </Heading>
   </xsl:template>

   <xsl:template match="w:p" name="para">
      <Paragraph>
         <xsl:apply-templates/>
      </Paragraph>
   </xsl:template>

   <xsl:template match="w:r/w:t">
      <xsl:value-of select="."/>
   </xsl:template>
</xsl:stylesheet>

入力 XML に適用すると、以下が出力されます。

<Document>
   <Paragraph>Text1-</Paragraph>
   <Heading>
      <Paragraph>Text2-</Paragraph>
   </Heading>
   <Paragraph>Text3-</Paragraph>
   <Paragraph>Text4-</Paragraph>
   <Heading>
      <Paragraph>Text5-</Paragraph>
   </Heading>
</Document>

実際には、 の最終的なテンプレート<xsl:template match="w:r/w:t">は厳密には必要ありません。特定のテンプレートがない要素に一致する XSLT のデフォルトの動作は、とにかくテキストを出力することだからです。

于 2012-06-22T06:36:19.573 に答える
0

何が間違っているかの非常に簡単な例として、あなたの xsl:otherwise ブロックは<xsl:apply-templates select="w:p">. この時のコンテキストノードはルートノード(/)なので、これはルートノードの子であるw:p要素を処理しており、そのような要素はないので何もしません。

ここでは、XSLT の経験がほとんどない非常に複雑な XML に取り組んでいます。最初にいくつかの簡単な問題に取り組む方がよい場合があります。XSLT の教科書やチュートリアルを読んで、例を試してみてください。

于 2012-06-22T09:05:24.083 に答える