使用 XSLT 从 Word-Document 中提取文本

Extract text from Word-Document using XSLT

我必须使用 XSLT 从 Word-document 中提取段落(意思是:标题及其内容)。我已经分析了结构并且可以使用 XSLT 到达 .docx-file 中的必要节点。但是现在我不知道如何在标题之间对 w:t 标签的内容进行分组,因为 Word 以一种非常奇怪的方式拆分文本。

input-data 看起来像:

<w:body xmlns:w="somenamespace">
   <w:p>
      <w:pPr> <w:pStyle w:val="Heading1" /> </w:pPr>
      <w:r> <w:t>My Headl</w:t> </w:r>
      <w:r> <w:t>ine</w:t> </w:r>
   </w:p>
   <w:p>
      <w:r> <w:t>text 1.1.1 </w:t> </w:r>
      <w:r> <w:t>text 1.1.2 </w:t> </w:r>
   </w:p>
   <w:p>
      <w:r> <w:t>text 1.2.1 </w:t> </w:r>
      <w:r> <w:t>text 1.2.2 </w:t> </w:r>
   </w:p>
   <w:p>
      <w:pPr> <w:pStyle w:val="Heading1" /> </w:pPr>
      <w:r> <w:t>My seco</w:t> </w:r>
      <w:r> <w:t>nd Headline</w:t> </w:r>
   </w:p>
   <w:p>
      <w:r> <w:t>text 2.1.1 </w:t> </w:r>
      <w:r> <w:t>text 2.1.2 </w:t> </w:r>
   </w:p>
   <w:p>
      <w:r> <w:t>text 2.2.1 </w:t> </w:r>
      <w:r> <w:t>text 2.2.2 </w:t> </w:r>
   </w:p>
</w:body>

拼接单个段落的内容是没有问题的。所以很容易将数据合并成一个紧凑的结构,如下所示:

<Document>
    <Paragraphs>
        <Headline>My Headline</Headline>
        <Content>text 1.1.1 text 1.1.2 </Content>
        <Content>text 1.2.1 text 1.2.2 </Content>
        <Headline>My second Headline</Headline>
        <Content>text 2.1.1 text 2.1.2 </Content>
        <Content>text 2.2.1 text 2.2.2 </Content>
    </Paragraphs>
</Document>

但是这种结构并不总是有用的,因为它仍然没有xml-element一段的内容。 那么有谁知道如何合并 之间的所有段落 w:p 元素代表标题? 我想要一个 XSLT 将 w:body-content 转换为如下结构:

<Document>
    <Paragraph>
        <Headline>My Headline</Headline>
        <Content>text 1.1.1 text 1.1.2 text 1.2.1 text 1.2.2 </Content>
    </Paragraph>
    <Paragraph>
        <Headline>My second Headline</Headline>
        <Content>text 2.1.1 text 2.1.2 text 2.2.1 text 2.2.2 </Content>
    </Paragraph>
</Document>

我发现了什么:

这可能是您问题的解决方案。您需要在 xslt 中使用 for-each-group 语句。您可以匹配整个 w:p 元素,并定义组的第一个元素是定义标题样式的 w:p。之后,您可以使用 current-group 函数获取项目,该函数为您提供组的 while node-array。

XSLT:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="somenamespace">
  <xsl:output method="xml" omit-xml-declaration="yes" />


  <xsl:template match="w:body">
    <Document>
      <xsl:for-each-group select="w:p" group-starting-with="*[./w:pPr/w:pStyle[@w:val='Heading1']]">
            <xsl:element name="Paragraph">
                <xsl:element name="Headline">
                    <xsl:value-of select="current-group()[1]/*/w:t/text()" />
                </xsl:element>
                <xsl:element name="Content">
                    <xsl:for-each select="current-group()[position()>1]/*">
                            <xsl:copy-of select="./w:t/text()" />
                    </xsl:for-each>
                </xsl:element>
            </xsl:element>
      </xsl:for-each-group>
    </Document>
  </xsl:template>

  <xsl:template match="*|node()">
    <xsl:apply-templates />
  </xsl:template>
</xsl:stylesheet>

输出:

<Document xmlns:w="somenamespace">
  <Paragraph>
    <Headline>My Headline</Headline>
    <Content>text 1.1.1 text 1.1.2 text 1.2.1 text 1.2.2 </Content>
  </Paragraph>
  <Paragraph>
    <Headline>My second Headline</Headline>
    <Content>text 2.1.1 text 2.1.2 text 2.2.1 text 2.2.2 </Content>
  </Paragraph>
</Document>