1

XML の次の部分があります (これはODFです) 。

<office:body>
    <office:text text:use-soft-page-breaks="true">
        <text:h text:style-name="P1" text:outline-level="1">Heading 1</text:h>
        <text:p text:style-name="P2">Paragraph 1</text:p>
        <text:h text:style-name="P3" text:outline-level="2">Heading 2</text:h>
        <text:p text:style-name="P4">Paragraph 2</text:p>
        <text:p text:style-name="P5">Paragraph 3</text:p>
        <text:h text:style-name="P6" text:outline-level="3">Heading 3</text:h>
        <text:p text:style-name="P7">Paragraph 4</text:p>
        <text:p text:style-name="P8">Paragraph 5</text:p>
        <text:p text:style-name="P9">Paragraph 6</text:p>
        <text:h text:style-name="P10" text:outline-level="4">Heading 4</text:h>
        <text:p text:style-name="P11">Paragraph 7</text:p>
        <text:h text:style-name="P12" text:outline-level="2">Heading 2</text:h>
        <text:p text:style-name="P13">Paragraph 8</text:p>
        <text:p text:style-name="P14">Paragraph 9</text:p>
        <text:p text:style-name="Normal">
            <text:span text:style-name="T15">Paragraph 10</text:span>
        </text:p>
    </office:text>
</office:body>

これを次のように変換する必要があります

<Blocks>
    <Block>
        <Title><![CDATA[Heading 2]]></Title>
        <Content>
            <![CDATA[<p>Paragraph 2</p><p>Paragraph 3</p><h3>Heading 3</h3><p>Paragraph 4</p><p>Paragraph 5</p><p>Paragraph 6</p><h4>Heading 4</h4><p>Paragraph 7</p>]]>
        </Content>
    </Block>
    <Block>
        <Title><![CDATA[Heading 2]]></Title>
        <Content>
            <![CDATA[<p>Paragraph 8</p><p>Paragraph 9</p><p>Paragraph 10</p>]]>
        </Content>
    </Block>
</Blocks>

ご覧のとおり、ノードBlockごとに要素を作成したいと思います。text:h/@text:outline-level = 2

すべての後続text:pおよびtext:h/@text:outline-level > 2兄弟は、Content作成したばかりの要素内の要素に配置する必要がありBlockます。

どうすればそれを達成できますか?

4

1 に答える 1

1

部分的な解決策は次のとおりです。

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:office="http://example.com/office"
  xmlns:text="http://example.com/text"
  exclude-result-prefixes="office text">

<xsl:output indent="yes" cdata-section-elements="Title"/>

<xsl:key 
  name="k1"
  match="text:p"
  use="generate-id(preceding-sibling::text:h[@text:outline-level = 2][1])"/>

<xsl:key 
  name="k1"
  match="text:h[@text:outline-level > 2]"
  use="generate-id(preceding-sibling::text:h[@text:outline-level = 2])"/>

<xsl:template match="office:text">
  <Blocks>
    <xsl:apply-templates select="text:h[@text:outline-level = 2]"/>
  </Blocks>
</xsl:template>

<xsl:template match="text:h[@text:outline-level = 2]">
  <Block>
    <Title>
      <xsl:value-of select="."/>
    </Title>
    <Content>
      <xsl:apply-templates select="key('k1', generate-id())"/>
    </Content>
  </Block>
</xsl:template>

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

<xsl:template match="text:h[@text:outline-level = 3]">
  <h3>
    <xsl:apply-templates/>
  </h3>
</xsl:template>

<xsl:template match="text:h[@text:outline-level = 4]">
  <h4>
    <xsl:apply-templates/>
  </h4>
</xsl:template> 

</xsl:stylesheet>

変形する

<office:body xmlns:office="http://example.com/office" xmlns:text="http://example.com/text">
    <office:text text:use-soft-page-breaks="true">
        <text:h text:style-name="P1" text:outline-level="1">Heading 1</text:h>
        <text:p text:style-name="P2">Paragraph 1</text:p>
        <text:h text:style-name="P3" text:outline-level="2">Heading 2</text:h>
        <text:p text:style-name="P4">Paragraph 2</text:p>
        <text:p text:style-name="P5">Paragraph 3</text:p>
        <text:h text:style-name="P6" text:outline-level="3">Heading 3</text:h>
        <text:p text:style-name="P7">Paragraph 4</text:p>
        <text:p text:style-name="P8">Paragraph 5</text:p>
        <text:p text:style-name="P9">Paragraph 6</text:p>
        <text:h text:style-name="P10" text:outline-level="4">Heading 4</text:h>
        <text:p text:style-name="P11">Paragraph 7</text:p>
        <text:h text:style-name="P12" text:outline-level="2">Heading 2</text:h>
        <text:p text:style-name="P13">Paragraph 8</text:p>
        <text:p text:style-name="P14">Paragraph 9</text:p>
        <text:p text:style-name="Normal">
            <text:span text:style-name="T15">Paragraph</text:span>
        </text:p>
    </office:text>
</office:body>

の中へ

<Blocks>
   <Block>
      <Title><![CDATA[Heading 2]]></Title>
      <Content>
         <p>Paragraph 2</p>
         <p>Paragraph 3</p>
         <h3>Heading 3</h3>
         <p>Paragraph 4</p>
         <p>Paragraph 5</p>
         <p>Paragraph 6</p>
         <h4>Heading 4</h4>
         <p>Paragraph 7</p>
      </Content>
   </Block>
   <Block>
      <Title><![CDATA[Heading 2]]></Title>
      <Content>
         <p>Paragraph 8</p>
         <p>Paragraph 9</p>
         <p>
            Paragraph
        </p>
      </Content>
   </Block>
</Blocks>

したがって、グループ化は私が知る限り行われますがp、2番目の最後のBlockものは必要な出力に表示されませんが、口頭での説明として「すべての次のテキスト:p」が示唆されていないため、それ以外の場合はその説明に従ってグループ化しました。

さらに欠けているのは、これらすべてphx要素を CDATA セクションに詰め込むことです。あなたが本当にそれを望んでいるかどうかはわかりませ。拡張関数を使用して、ノードをテキストにシリアル化します。また、結果ツリー フラグメントを使用し、 exsl:node-set などを使用して、結果ツリー フラグメントをシリアライズ用のノード セットに変換する必要がある場合もあります。text:p別の方法として、要素ノードの代わりにマークアップ付きのテキスト ノードを出力するように、 およびその他のテンプレートを変更する必要があります。

于 2012-07-09T18:13:20.017 に答える