我有一个XLIFF文件,我将其用于将iPhone应用程序翻译成其他语言。
以下是它的样子:
df[['Cat1','Cat2','Cat3']]
现在我需要做以下事情:
我的翻译已经在文本文件中,格式如下:
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.2"
xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 http://docs.oasis-open.org/xliff/v1.2/os/xliff-core-1.2-strict.xsd">
<file original="kWallet/Base.lproj/BonusProgram.storyboard"
source-language="de"
datatype="plaintext"
target-language="en">
<header>
<tool tool-id="com.apple.dt.xcode"
tool-name="Xcode"
tool-version="8.2.1"
build-num="8C1002"/>
</header>
<body>
<trans-unit id="VNf-SH-yf4.normalTitle">
<source>Nicht mehr teilnehmen</source>
<target>Nicht mehr teilnehmen</target>
<note>Class = "UIButton"; normalTitle = "Nicht mehr teilnehmen"; ObjectID = "VNf-SH-yf4";</note>
</trans-unit>
<trans-unit id="bks-T0-HXe.normalTitle">
<source>Teilnehmen</source>
<target>Teilnehmen</target>
<note>Class = "UIButton"; normalTitle = "Teilnehmen"; ObjectID = "bks-T0-HXe";</note>
</trans-unit>
<trans-unit id="inq-dy-gMC.title">
<source>Bonus</source>
<target>Bonus</target>
<note>Class = "UITabBarItem"; title = "Bonus"; ObjectID = "inq-dy-gMC";</note>
</trans-unit>
<trans-unit id="mub-0G-Dk1.title">
<source>Bonus Program</source>
<target>Bonus Program</target>
<note>Class = "UINavigationItem"; title = "Bonus Program"; ObjectID = "mub-0G-Dk1";</note>
</trans-unit>
<trans-unit id="rAv-9a-ssv.title">
<source>Bonus</source>
<target>Bonus</target>
<note>Class = "UINavigationItem"; title = "Bonus"; ObjectID = "rAv-9a-ssv";</note>
</trans-unit>
</body>
</file>
</xliff>
,例如"source" = "target"
"Im App Store anzeigen" = "Show in App Store"
所以我要创建一个脚本,它读取我的文本文件并在每一行之后调用xslt变换,并传递2个值。
现在我需要了解如何使用xslt解决转换问题。基本上它需要搜索/* Show in App Store Text */
"Im App Store anzeigen" = "Show in App Store";
,然后用我将要传递给xslt转换器的第二个值替换它的<source> == "Nicht mehr teilnehmen"
兄弟(在这种情况下<target>
)
我认为这应该很简单,但遗憾的是我没有足够的经验使用xslt来解决这个问题。谢谢你的帮助。
答案 0 :(得分:1)
如果您能够使用XSLT 2.0或更新版本,则以下方法可行。 XSLT 1.0中不存在三种不同的功能。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0"
xpath-default-namespace="urn:oasis:names:tc:xliff:document:1.2">
<!-- Note the `xpath-default-namespace` line here: this is only allowed in XSLT 2.0 and newer.
The input XLIFF file itself specifies this URI as the unprefixed namespace for the whole file.
If we don't specify this as the XPath default namespace, we have to specify element names
in ugly workaround syntax, such as `*[local-name() = 'xliff']`. -->
<!-- Parameter for feeding in the path to your translated-pairs text file. -->
<xsl:param name="transfile-path" select="'DEFAULTPATH'"/>
<!-- Sample path format: 'file:///C:/Users/[USERNAME]/AppData/Local/Temp/transdata.txt' -->
<!-- Variable containing whole content of your translated-pairs text file. Replace the file path as appropriate.
The `unparsed-text` XPath function is required to load plain text (as opposed to parsable XML).
This function is only available in XSLT 2.0 or newer. -->
<xsl:variable name="transfile" select="unparsed-text($transfile-path)"/>
<!-- Newline: this might need adjusting, depending on the newline format in your text file. -->
<xsl:variable name="newline" select="'
'"/>
<xsl:template match="/xliff|file|body|trans-unit">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="header|source|note">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="target">
<xsl:copy>
<!-- This variable tokenizes the $transfile content by newline,
then grabs the first line where the source matches the current <target> element text
(wrapped with double-quotes, just in case),
then chops off the source portion and stores just the target portion, but with the last " on the end.
The `tokenize` XPath function requires XSLT 2.0 or newer. -->
<xsl:variable name="target-string" select="substring-after(tokenize($transfile, $newline)
[contains(., concat('"', current(), '"'))][1], '" = "')"/>
<!-- Output the target string, minus that last " -->
<xsl:value-of select="substring($target-string, 1, string-length($target-string) - 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用包含您指定格式的翻译对的简单文本文件,以上内容适用于我。我试图包含信息性评论,以了解代码的作用。
这假设您的数据完全一对一。因此"Fussbodenschleifmaschinenverleih"
可能会在翻译对文本文件中出现14次,但始终且仅翻译为相同的目标字符串。 :)
如果您或您的团队有权访问CAT tool,许多此类工具都会包含"alignment" feature或随播应用,可以像您所描述的那样获取双语数据,并生成翻译记忆库。根据您的设置,这可能会更容易。
根据gasparuff的评论,以下是如何从<source>
元素而不是直接从<target>
元素查找源文本的方法。这涉及对前一代码的单一更改:
<xsl:variable name="target-string" select="substring-after(tokenize($transfile, $newline)
[contains(., concat('"', current()/../source, '"'))][1], '" = "')"/>
<!-- The previous version had `current()`, as in, the content of the current
context element, which is here the <target> element. I changed that above to
`current()/../source` to instead get the text from the sibling <source>
element. .. here evaluates to the parent of the current <target>, and then
we look for the <source> child of that parent. This is often safer than
using preceding-sibling::source, or following-sibling::source, since we
often cannot say 100% that the element we're looking for is *before* the
current context element, or *after* it. -->