首页 > 解决方案 > 需要从一个以标记拆分的奇怪 xml 文件构建整个句子

问题描述

我使用 XSLT 处理 NLP 项目,我需要使用以下 XML 文档创建句子:

<?xml version="1.0" encoding="UTF-8"?>
<cordial2xml>
<w><forme>la</forme><lemme>le</lemme><categorie>DETDFS</categorie></w><w><forme>grande</forme><lemme>grand</lemme><categorie>ADJFS</categorie></w><w><forme>douleur</forme><lemme>douleur</lemme><categorie>NCFS</categorie></w><w><forme>du</forme><lemme>du</lemme><categorie>DETDMS</categorie></w><w><forme>père</forme><lemme>père</lemme><categorie>NCMS</categorie></w><w><forme>duchesne</forme><lemme>duchesne</lemme><categorie>NCMS</categorie></w>
<w><forme>au sujet de</forme><lemme>au sujet de</lemme><categorie>PREP</categorie></w><w><forme>la</forme><lemme>le</lemme><categorie>DETDFS</categorie></w><w><forme>mort</forme><lemme>mort</lemme><categorie>NCFS</categorie></w><w><forme>de</forme><lemme>de</lemme><categorie>PREP</categorie></w><w><forme>marat</forme><lemme>marat</lemme><categorie>NPMS</categorie></w><w><forme>assassiné</forme><lemme>assassiner</lemme><categorie>VPARPMS</categorie></w><w><forme>à</forme><lemme>à</lemme><categorie>PREP</categorie></w>
<w><forme>coups</forme><lemme>coup</lemme><categorie>NCMP</categorie></w><w><forme>de</forme><lemme>de</lemme><categorie>PREP</categorie></w><w><forme>couteau</forme><lemme>couteau</lemme><categorie>NCMS</categorie></w><w><forme>par</forme><lemme>par</lemme><categorie>PREP</categorie></w><w><forme>une</forme><lemme>un</lemme><categorie>DETIFS</categorie></w><w><forme>garce</forme><lemme>gars</lemme><categorie>NCFS</categorie></w><w><forme>du</forme><lemme>du</lemme><categorie>DETDMS</categorie></w><w><forme>calvados</forme><lemme>calvados</lemme><categorie>NCMIN</categorie></w><w><forme>,</forme><lemme>,</lemme><categorie>PCTFAIB</categorie></w>
<w><forme>dont</forme><lemme>dont</lemme><categorie>PRI</categorie></w><w><forme>l'</forme><lemme>le</lemme><categorie>DETDMS</categorie></w><w><forme>évêque</forme><lemme>évêque</lemme><categorie>NCMS</categorie></w><w><forme>fauchet</forme><lemme>fauchet</lemme><categorie>NCMS</categorie></w><w><forme>était</forme><lemme>être</lemme><categorie>VINDI3S</categorie></w><w><forme>le</forme><lemme>le</lemme><categorie>DETDMS</categorie></w><w><forme>directeur.ses</forme><lemme>directeur.ses</lemme><categorie>NCI</categorie></w>
<w><forme>bons</forme><lemme>bon</lemme><categorie>ADJMP</categorie></w><w><forme>avis</forme><lemme>avis</lemme><categorie>NCMIN</categorie></w><w><forme>aux</forme><lemme>au</lemme><categorie>DETDPIG</categorie></w><w><forme>braves</forme><lemme>brave</lemme><categorie>NCPIG</categorie></w><w><forme>sans</forme><lemme>sans</lemme><categorie>PREP</categorie></w><w><forme>-culottes</forme><lemme>culotte</lemme><categorie>NCFP</categorie></w><w><forme>pour</forme><lemme>pour</lemme><categorie>PREP</categorie></w>
<w><forme>qu'</forme><lemme>que</lemme><categorie>SUB</categorie></w><w><forme>ils</forme><lemme>il</lemme><categorie>PPER3P</categorie></w><w><forme>se</forme><lemme>se</lemme><categorie>PPER3S</categorie></w><w><forme>tiennent</forme><lemme>tenir</lemme><categorie>VINDP3P</categorie></w><w><forme>sur</forme><lemme>sur</lemme><categorie>PREP</categorie></w><w><forme>leurs</forme><lemme>leur</lemme><categorie>DETPOSS</categorie></w><w><forme>gardes</forme><lemme>garde</lemme><categorie>NCFP</categorie></w><w><forme>,</forme><lemme>,</lemme><categorie>PCTFAIB</categorie></w>
<w><forme>attendu qu'</forme><lemme>attendu que</lemme><categorie>SUB</categorie></w><w><forme>il</forme><lemme>il</lemme><categorie>PPER3S</categorie></w><w><forme>y</forme><lemme>y</lemme><categorie>PPER3S</categorie></w><w><forme>a</forme><lemme>avoir</lemme><categorie>VINDP3S</categorie></w><w><forme>dans</forme><lemme>dans</lemme><categorie>PREP</categorie></w><w><forme>paris</forme><lemme>pari</lemme><categorie>NCMP</categorie></w><w><forme>plusieurs</forme><lemme>plusieurs</lemme><categorie>ADJIND</categorie></w><w><forme>milliers</forme><lemme>millier</lemme><categorie>NCMP</categorie></w>
<w><forme>de</forme><lemme>de</lemme><categorie>PREP</categorie></w><w><forme>tondus</forme><lemme>tondu</lemme><categorie>ADJMP</categorie></w><w><forme>de</forme><lemme>de</lemme><categorie>PREP</categorie></w><w><forme>la</forme><lemme>le</lemme><categorie>DETDFS</categorie></w><w><forme>vendée</forme><lemme>vendée</lemme><categorie>NPFS</categorie></w><w><forme>qui</forme><lemme>qui</lemme><categorie>PRI</categorie></w><w><forme>ont</forme><lemme>avoir</lemme><categorie>VINDP3P</categorie></w><w><forme>la</forme><lemme>le</lemme><categorie>DETDFS</categorie></w><w><forme>patte</forme><lemme>patte</lemme><categorie>NCFS</categorie></w>
<w><forme>graissée</forme><lemme>graisser</lemme><categorie>VPARPFS</categorie></w><w><forme>pour</forme><lemme>pour</lemme><categorie>PREP</categorie></w><w><forme>égorger</forme><lemme>égorger</lemme><categorie>VINF</categorie></w><w><forme>tous</forme><lemme>tout</lemme><categorie>ADJMP</categorie></w><w><forme>les</forme><lemme>le</lemme><categorie>DETDPIG</categorie></w><w><forme>bons</forme><lemme>bon</lemme><categorie>ADJMP</categorie></w><w><forme>citoyens</forme><lemme>citoyen</lemme><categorie>NCMP</categorie></w><w><forme>.</forme><lemme>.</lemme><categorie>PCTFORTE</categorie></w>
<w><forme>marat</forme><lemme>marat</lemme><categorie>NPMS</categorie></w><w><forme>n'</forme><lemme>ne</lemme><categorie>ADV</categorie></w><w><forme>est</forme><lemme>être</lemme><categorie>VINDP3S</categorie></w><w><forme>plus</forme><lemme>plus</lemme><categorie>ADV</categorie></w><w><forme>,</forme><lemme>,</lemme><categorie>PCTFAIB</categorie></w><w><forme>foutre.peuple</forme><lemme>foutre.peuple</lemme><categorie>NCI</categorie></w><w><forme>,</forme><lemme>,</lemme><categorie>PCTFAIB</categorie></w><w><forme>gémis</forme><lemme>gémir</lemme><categorie>VPARPMP</categorie></w><w><forme>,</forme><lemme>,</lemme><categorie>PCTFAIB</categorie></w>
<w><forme>pleure</forme><lemme>pleurer</lemme><categorie>VIMPP2S</categorie></w><w><forme>ton</forme><lemme>ton</lemme><categorie>DETPOSS</categorie></w><w><forme>meilleur</forme><lemme>meilleur</lemme><categorie>ADJMS</categorie></w><w><forme>ami</forme><lemme>ami</lemme><categorie>NCMS</categorie></w><w><forme>;</forme><lemme>;</lemme><categorie>PCTFORTE</categorie></w>
<w><forme>il</forme><lemme>il</lemme><categorie>PPER3S</categorie></w><w><forme>meurt</forme><lemme>mourir</lemme><categorie>VINDP3S</categorie></w><w><forme>martyr</forme><lemme>martyr</lemme><categorie>ADJMS</categorie></w><w><forme>de</forme><lemme>de</lemme><categorie>PREP</categorie></w>
</cordial2xml>

它只是这个 XML 文档的一部分。从中,我需要构造句子,所以我需要将表单节点与空格连接起来并停止,直到一个单词之间有一个点(句末)或只有“。” 对于按点切割成 2 的最后一个单词,我需要在当前句子的 point 之前保留第一个 sustring,之后的 sustring 将成为新句子的开头。问题是,我不知道该怎么做。我不知道我是否创建了一个匹配//w 的模板,但当时我无法确定只有单词,所以我需要所有节点,直到 frome 包含“。”的节点 保留第一个包含 '.' 的子字符串形式 在当前句子和 '.' 之后的后缀中 是新句子的第一个词 实际上,对于前 2 个句子,

<p>la grande douleur du pere duchesne au sujet de la mort de marat à coups de couteau par un gard du calvados, l'eveque fauchet etait le directeur.</p>

<p>bons avis au brave sans culottes pour que se tiennent sur leurs gardes, attendu qu'il a dans paris plusieurs milliers de tondus de la vendée qui ont la patte grasser pour egorger tous les bons citoyens.<p>
etc...

在开始时,我想应用一个递归模板来创建每个句子,但是如何保持下面的单词被切割,但下一个句子的重点。我也可以使用模板匹配 //w 但我不知道如何处理 xslt 代码标签中的 p 我可以捕获当前节点和表单包含“。”的节点之间的所有节点 像这样 w[1]/following-sibling::*[not(contains(./forme, '.'))][1] (第一个 w 和最后一个 w 之间的分组节点包含 '.' 并递归.绝对的第一个形式是第一句话的开头。你有什么想法来完成我的任务吗?我迷路了。我不需要代码而是方法。如果你有代码段,最好当然。非常感谢。

标签: xmlxsltxpathnlp

解决方案


我会分两遍来做:首先,通过连接所有单词来构建一个完整的段落,用空格分隔。然后使用句点字符作为分隔符将段落拆分为句子。

由于您(在另一个问题中)说您正在使用libxslt处理器,因此您可以使用扩展函数来执行第二遍。

这是一个简化的示例:

XML

<root>
    <word>Joe</word>
    <word>waited</word>
    <word>for</word>
    <word>the</word>
    <word>train.</word>
    <word>The</word>
    <word>train</word>
    <word>was</word>
    <word>late.Meanwile</word>
    <word>Mary</word>
    <word>and</word>
    <word>Samantha</word>
    <word>took</word>
    <word>the</word>
    <word>bus.</word>
    <word>Orphan</word>
</root>

XSLT 1.0 + EXSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/root">
    <!-- first pass -->
    <xsl:variable name="para">
        <xsl:for-each select="word">
            <xsl:value-of select="." />
            <xsl:if test="position()!=last()">
                <xsl:text> </xsl:text>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <output>
        <xsl:for-each select="str:tokenize($para, '.')">
            <sentence>
                <xsl:value-of select="normalize-space(.)" />
                <xsl:text>.</xsl:text>
            </sentence>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<output>
  <sentence>Joe waited for the train.</sentence>
  <sentence>The train was late.</sentence>
  <sentence>Meanwile Mary and Samantha took the bus.</sentence>
  <sentence>Orphan.</sentence>
</output>

添加:

实际上我使用的是 Saxon 9。

那么,您可以将其进一步简化为:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/root">
    <xsl:variable name="para">
        <xsl:value-of select="word"/>
    </xsl:variable>
    <output>
        <xsl:for-each select="tokenize($para, '\.')">
            <sentence>
                <xsl:value-of select="normalize-space(.)" />
                <xsl:text>.</xsl:text>
            </sentence>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

推荐阅读