使用 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>
我发现了什么:
如果一个 w:p
元素包含一个 w:pPr
元素,那么它总是这个 w:p
元素的第一个 child-node
如果 w:p
元素匹配此条件 ./w:pPr/w:pStyle[@w:val='Heading1']>
,则此 w:p
元素中的所有 w:r
元素都属于标题段落的。
这可能是您问题的解决方案。您需要在 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>
我必须使用 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>
我发现了什么:
如果一个
w:p
元素包含一个w:pPr
元素,那么它总是这个w:p
元素的第一个 child-node如果
w:p
元素匹配此条件./w:pPr/w:pStyle[@w:val='Heading1']>
,则此w:p
元素中的所有w:r
元素都属于标题段落的。
这可能是您问题的解决方案。您需要在 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>