XSLT: предшествующий элемент, возможно, не одноуровневый, но не пересекающий определенный тег - PullRequest
0 голосов
/ 20 мая 2011

Я пытаюсь выполнить канонизацию текста, чтобы заменить некоторые сокращения. Вот несколько примеров ввода:

<?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')=&quot;'s&quot;][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')=&quot;'s&quot;][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.

Спасибо за любые советы, которые вы можете дать!

1 Ответ

2 голосов
/ 20 мая 2011

Это преобразование отвечает всем требованиям :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <my:AposS>'s</my:AposS>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
  "w[. = document('')/*/my:AposS
   and
     not(generate-id()
        =
         generate-id(ancestor::s[1]/descendant::w[1])
         )
   and
     preceding::w[1] = 'Here'
    ]
  ">
  <w>is</w>
 </xsl:template>

 <xsl:template match=
  "w[. = document('')/*/my:AposS
   and
     not(generate-id()
        =
         generate-id(ancestor::s[1]/descendant::w[1])
         )
   and
     preceding::w[1] = 'let'
    ]
  ">
  <w>us</w>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<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>

желаемый результат получен :

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...