我正在尝试以某种格式处理从pdf转换为另一个xml文件的xml。首先,我想根据文本的几何图形将一些文本/节点移动/分组,但未能这样做。以下是我的输入&我想要的是什么:
输入xml:
part_func
输出xml:
<Pages>
<Page>
<PAGENUMBER>1</PAGENUMBER>
<Box llx="59.40" lly="560.64" urx="68.58" ury="571.68">
<Text>5.</Text>
</Box>
<Box llx="81.84" lly="560.64" urx="194.39" ury="571.68">
<Text>Equipment list</Text>
</Box>
<Box llx="257.40" lly="560.64" urx="265.36" ury="571.68">
<Text>C</Text>
</Box>
<Box llx="315.84" lly="535.32" urx="325.63" ury="546.36">
<Text>a)</Text>
</Box>
</Page>
<Page>
same structure as above...
</Page>
</Pages>
我有什么:
<Pages>
<Page>
<PAGENUMBER>1</PAGENUMBER>
<Box llx="59.40" lly="560.64" urx="68.58" ury="571.68">
<Text>5. Equipment list C</Text>
</Box>
<Box llx="315.84" lly="535.32" urx="325.63" ury="546.36">
<Text>a)</Text>
</Box>
</Page>
<Page>
same structure as above...
</Page>
</Pages>
1.它不复制有用节点2.我不知道如何排除以下节点。我希望有人可以帮助我。非常感谢提前。
我尝试了以下操作来排除重复项,但它不会复制我想要的内容:
<xsl:template match="@*|node()" name = "identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Box">
<xsl:choose>
<xsl:when test="@ury = following-sibling::Box/@ury">
<xsl:call-template name="identity"/>
<xsl:apply-templates select ="@*"/>
<xsl:copy-of select="following-sibling::Box/Text"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 0 :(得分:1)
这是muenchian grouping的情况,您需要根据某些通用条件对节点进行分组,并对它们进行处理以提供输出。
根据所使用的XSLT版本,XSLT 1.0和XSLT 2.0的解决方案不同
XSLT 1.0
1.0版使用<xsl:key>
根据通用标准对元素进行分组。在这种情况下,分组是基于属性@ury
的值完成的,因此我们定义了一个键
<xsl:key name="groupingKey" match="Box" use="@ury" />
使用此键,模板被组合在一起进行处理。
<xsl:template match="Box[generate-id() = generate-id(key('groupingKey', @ury)[1])]">
最后在分组元素中,在<Text>
元素上运行循环以连接其值。
<Text>
<xsl:variable name="fullText">
<xsl:for-each select="key('groupingKey', @ury)/Text">
<xsl:value-of select="concat(., ' ')" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="normalize-space($fullText)" />
</Text>
以下是完整的XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="groupingKey" match="Box" use="@ury" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Box[generate-id() = generate-id(key('groupingKey', @ury)[1])]">
<xsl:copy>
<xsl:apply-templates select="@*" />
<Text>
<xsl:variable name="fullText">
<xsl:for-each select="key('groupingKey', @ury)/Text">
<xsl:value-of select="concat(., ' ')" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="normalize-space($fullText)" />
</Text>
</xsl:copy>
</xsl:template>
<xsl:template match="Box" />
</xsl:stylesheet>
XSLT 2.0
与XSLT 1.0相比,2.0版是先进的,并提供了一种更简单的方法。 <xsl:for-each-group>
和group-by
功能可用于将元素组合在一起。
<xsl:for-each-group select="Box" group-by="@ury">
以下是完整的XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Page">
<xsl:copy>
<xsl:apply-templates select="PAGENUMBER" />
<xsl:for-each-group select="Box" group-by="@ury">
<xsl:copy>
<xsl:apply-templates select="@*" />
<Text>
<xsl:variable name="fullText">
<xsl:for-each select="current-group()/Text">
<xsl:value-of select="concat(., ' ')" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="normalize-space($fullText)" />
</Text>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XSLT都提供了所需的输出
<Pages>
<Page>
<PAGENUMBER>1</PAGENUMBER>
<Box llx="59.40" lly="560.64" urx="68.58" ury="571.68">
<Text>5. Equipment list C</Text>
</Box>
<Box llx="315.84" lly="535.32" urx="325.63" ury="546.36">
<Text>a)</Text>
</Box>
</Page>
</Pages>