我必须使用XSLT从Word文档中提取段落(意味着:标题及其内容)。我已经分析了结构,并可以使用XSLT到达.docx文件中的必要节点。但是现在我不知道如何在标题之间对w:t
标签的内容进行分组,因为Word以一种非常奇怪的方式拆分了文本。
输入数据如下:
<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元素。
那么,有谁知道如何在代表标题的w:p
元素的之间合并所有段落?
我想要一个XSLT,它可以将w:body
-内容转换为类似这样的结构:
<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
元素的第一个子节点
如果在此条件w:p
上匹配一个./w:pPr/w:pStyle[@w:val='Heading1']>
元素,则该w:r
元素中的所有w:p
元素都属于该段落的标题。
答案 0 :(得分:1)
这可能是解决您问题的方法。您需要在xslt中使用for-each-group
语句。您可以匹配整个w:p
元素,并定义组的第一个元素是定义标题样式的w:p
。之后,您可以使用current-group
函数获取项目,该函数为您提供该组的while节点数组。
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>