Я пытаюсь выполнить канонизацию текста, чтобы заменить некоторые сокращения. Вот несколько примеров ввода:
<?xml version="1.0"?>
<transcript>
<p id="p1">
<s id="s1"><w>Here</w><w>'s</w> <w>an</w> <w>example</w>, <w>let</w><w>'s</w> <w>consider</w> <w>it</w></s>
<s id="s2"><w>Here</w> <w>'s</w> <w>an</w> <w>example</w>, <w>let</w><w>'s</w> <w>consider</w> <w>it</w></s>
<s id="s3"><foo><w>Here</w></foo><bar><w>'s</w></bar> <w>an</w> <w>example</w>, <foo><w>let</w></foo><w>'s</w> <w>consider</w> <w>it</w></s>
<s id="s4"><w>Here</w><bar><baz><w>'s</w></baz></bar> <w>an</w> <w>example</w>, <baz><bar><w>let</w></bar><w>'s</w></baz> <w>consider</w> <w>it</w></s>
<s id="s5"><w>Look</w> <w>here</w></s>
<s id="s6"><w>'s</w> <w>another</w> <w>example</w></s>
</p>
</transcript>
В этом примере я хочу заменить слова "здесь" на "ее" и "давайте" на "позволим нам". Таким образом, мой желаемый результат:
<?xml version="1.0"?>
<transcript>
<p id="p1">
<s id="s1"><w>Here</w> <w>is</w> <w>an</w> <w>example</w>, <w>let</w> <w>us</w> <w>consider</w> <w>it</w></s>
<s id="s2"><w>Here</w> <w>is</w> <w>an</w> <w>example</w>, <w>let</w> <w>us</w> <w>consider</w> <w>it</w></s>
<s id="s3"><foo><w>Here</w></foo> <bar><w>is</w></bar> <w>an</w> <w>example</w>, <foo><w>let</w></foo> <w>us</w> <w>consider</w> <w>it</w></s>
<s id="s4"><w>Here</w> <bar><baz><w>is</w></baz></bar> <w>an</w> <w>example</w>, <baz><bar><w>let</w></bar> <w>us</w></baz> <w>consider</w> <w>it</w></s>
<s id="s5"><w>Look</w> <w>here</w></s>
<s id="s6"><w>'s</w> <w>another</w> <w>example</w></s>
</p>
</transcript>
Мне удалось собрать некоторый (возможно, не совсем элегантный или оптимальный) код, который может обрабатывать s1
и s2
, но я не вижу возможности обобщить его для чего-то полезного.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="w[translate(text(),'S','s')="'s"][preceding-sibling::*[1]/self::w[translate(text(),'HERE','here')='here']]">
<xsl:text> </xsl:text>
<xsl:copy><xsl:copy-of select="@*"/>is</xsl:copy>
</xsl:template>
<xsl:template match="w[translate(text(),'S','s')="'s"][preceding-sibling::*[1]/self::w[translate(text(),'LET','let')='let']]">
<xsl:text> </xsl:text>
<xsl:copy><xsl:copy-of select="@*"/>us</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Некоторые детали:
Предположим, что все слова заключены в теги <w>
и что интересующие "слова" являются последовательными (хотя и не обязательно родными)
Произвольные теги могут переносить одно или другое или оба слова и буквы.
Подстановка не должна пересекать границы предложения <s>
(как показано в s5 и s6) - хотя, если это невозможно, я не буду плакать.
Если между словом и символами "s" уже есть пробел, я все равно хочу заменить их символами. Точный интервал результата (один пробел или два) не имеет значения.
В идеале пробел должен быть добавлен к ближайшему общему предку двух тегов <w>
, содержащих слово и 's.
Спасибо за любые советы, которые вы можете дать!