XSLT:前面的元素,可能不是同级元素,但不交叉特定标签

发布于 2024-11-09 02:14:12 字数 4250 浏览 0 评论 0原文

我正在尝试执行一些文本规范化来替换一些缩写。以下是一些示例输入:

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

在本例中,我想将“here's”替换为“hers is”,将“let's”替换为“let us”。因此,我想要的输出是,

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

我能够组合一些可以处理 s1s2 的代码(可能没有接近优雅或最佳的),但我没有看到我可以将其概括为有用的东西。

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

一些细节:

  • 假设单词全部包含在 标签中,并且感兴趣的“单词”是连续的(尽管不一定是兄弟)

  • 任意标签可以包裹单词和 的一个或另一个或两者。< /p>

  • 替换不应跨越句子边界(如s5和s6所示) - 尽管如果这是不可能的,我不会哭泣。

  • 如果单词和 ' 之间已经存在空格,我仍然想替换 ' 。结果的确切间距(一个或两个空格)并不重要。

  • 理想情况下,空格将添加到包含单词和 的两个 标记的最近公共祖先。

感谢您提供的任何指导!

I am attempting to perform some text canonicalization to replace some contractions. Here is some example input:

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

In this example, I want to replace "here's" with "hers is" and "let's" with "let us". Thus, my desired output is,

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

I was able to put together some (probably nothing near elegant or optimal) code that can handle s1 and s2, but I do not see that I can generalize it to something useful.

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

Some details:

  • Assume words are all wrapped in <w> tags and that the "words" of interest are consecutive (though not necessarily siblings)

  • Arbitrary tags may wrap one or the other or both of the word and the 's.

  • The substitution should not cross sentence <s> boundaries (as shown in s5 and s6) - though if this is impossible, I will not cry.

  • If a space already exists between word and 's, I still want to replace the 's. The exact spacing of the result (one space or two) does not matter.

  • Ideally, the space will be added to the nearest common ancestor of the two <w> tags containing the word and the 's.

Thanks for any guidance you can give!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千纸鹤带着心事 2024-11-16 02:14:13

此转换满足所有要求

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

This transformation fulfills all the requirements:

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

when applied on the provided XML document:

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

the wanted result is produced:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文