2012-07-09 27 views
1

我有一个XML的以下部分(这是ODF我怎样才能在平坦的XML组的兄弟姐妹

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

正如你所看到的,我想要为每个text:h/@text:outline-level = 2节点创建一个Block元素。

以下所有内容text:ptext:h/@text:outline-level > 2兄弟姐妹应放置在刚创建的Block元素内的Content元素中。

我该如何做到这一点?

回答

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在第二个Block不会出现在您的输出中,而是作为您的动词al描述“所有以下文本:p”不会建议,否则我按照该描述进行了分组。

什么是另外缺乏的是所有这些phx元素塞进一个CDATA部分,我不知道你真正想要的,如果是的话,我会建议抢东西像http://lenzconsulting.com/xml-to-string/或使用扩展功能序列的节点到文本。这可能还需要使用结果树片段,并使用exsl:node-set或类似的方法将结果树片段转换为用于序列化的节点集。作为替代方案,您需要更改text:p等模板以使用标记而不是元素节点输出文本节点。

+0

就是这样!我的主要问题是xsl:key,你完全为我解决了它。最后一个'p'是我的错,我在我的问题中澄清了它。 CDATA中的'p','h3'和'h4'是另一个问题:但经过几次尝试后,它终于与这个模板一起工作: <p> </p > Sandro 2012-07-10 08:57:21