2016-06-21 3 views
-1

Я достиг предела своих знаний XSLT со следующей проблемой.Как tokenize текст предложениями с XSLT

У меня есть файл XML, который выглядит следующим образом, упрощенный:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<p> 
    <w>This</w> 
    <w>is</w> 
    <w>a</w> 
    <w>sentence</w> 
    <w>with</w> 
    <w>a</w> 
    <entity type="name">Name</entity> 
    <w>and</w> 
    <w>a</w> 
    <entity type="place">Place</entity> 
    <w>etc</w>. <w>This</w> 
    <w>is</w> 
    <w>another</w> 
    <w>sentence</w> 
    <w>with</w> 
    <w>an</w> 
    <w>abbrev</w>. <w>before</w> 
    <w>its</w> 
    <w>end</w>. <w>Is</w> 
    <w>this</w> 
    <w>a</w> 
    <w>question</w>? <w>Sure</w> 
    <w>it</w> 
    <w>is</w>! </p> 
</root> 

Текст уже разбивается на лексемы слово. Мне нужно автоматически назначать предложения. Чтобы сделать это, у меня есть переменная, которая содержит возможные символы, которые заканчиваются предложение:

<xsl:variable name="SEnd">.!?</xsl:variable> 

Итак, мне нужен XSLT 2.0 таблицы стилей, которые будут:

  • цикл по каждому пункту
  • группы слов (<w>) вместе, начиная с первого <w> в абзаце и заканчивая элементом <w>, чей непосредственный родной узел text() начинается с одного из членов переменной «SEnd», но тогда и только тогда, когда following-sibling::w начинается с капитала письмо (это должно быть REGEX \p{Lu}, а не только [A-Z], потому что у меня есть несколько скриптов;
  • обернуть каждую из вышеупомянутых групп в <s></s>.

Этот способ <w>abbrev</w>. не будет признан последним словом предложения, поскольку за ним следует строчное слово.

Результат должен выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<p> 
    <s><w>This</w> 
     <w>is</w> 
     <w>a</w> 
     <w>sentence</w> 
     <w>with</w> 
     <w>a</w> 
     <entity type="name">Name</entity> 
     <w>and</w> 
     <w>a</w> 
     <entity type="place">Place</entity> 
     <w>etc</w>.</s> 
    <s><w>This</w> 
     <w>is</w> 
     <w>another</w> 
     <w>sentence</w> 
     <w>with</w> 
     <w>an</w> 
     <w>abbrev</w>. <w>before</w> 
     <w>its</w> 
     <w>end</w>.</s> 
    <s><w>Is</w> 
     <w>this</w> 
     <w>a</w> 
     <w>question</w>?</s> 
    <s><w>Sure</w>, 
     <w>it</w> 
     <w>is</w>!</s> 
</p> 
</root> 

Я знаю, что это не пуленепробиваемое, и что будет исключение, но это не важно для этой конкретной задачи. Я понимаю концепцию концептуально, и я думаю, что нужно использовать <xsl:for-each-group>, но я в затруднении, как на самом деле собрать все это вместе.

Я был бы очень признателен за вашу помощь.

Все лучшее, линь

ответ

1

Как насчет:

<xsl:template match="p"> 
    <xsl:copy> 
     <xsl:for-each-group select="node()" group-ending-with="text()[matches(., $SEnd)][matches(following-sibling::w[1], '^\p{Lu}')]"> 
      <s> 
       <xsl:apply-templates select="current-group()" /> 
      </s> 
     </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 
+0

да. да. да. Спасибо большое! теперь я, наконец, понимаю, что делает группа. – Tench