XSLT:前面的元素,可能不是同级元素,但不交叉特定标签
我正在尝试执行一些文本规范化来替换一些缩写。以下是一些示例输入:
<?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>
我能够组合一些可以处理 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>
一些细节:
假设单词全部包含在
标签中,并且感兴趣的“单词”是连续的(尽管不一定是兄弟)任意标签可以包裹单词和 的一个或另一个或两者。< /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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此转换满足所有要求:
应用于提供的 XML 文档时:
生成所需结果:
This transformation fulfills all the requirements:
when applied on the provided XML document:
the wanted result is produced: