Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 搜索值但用xslt替换同级_Xml_Xslt_Search_Replace - Fatal编程技术网

Xml 搜索值但用xslt替换同级

Xml 搜索值但用xslt替换同级,xml,xslt,search,replace,Xml,Xslt,Search,Replace,我有一个XLIFF文件,用于将iPhone应用程序翻译成另一种语言 下面是它的样子: <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.oasi

我有一个XLIFF文件,用于将iPhone应用程序翻译成另一种语言

下面是它的样子:

<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>
所以我将创建一个脚本,它读取我的文本文件,并在每行之后调用xslt转换,将2个值传递给它

现在我需要了解如何使用xslt解决转换。基本上,它需要搜索
==“Nicht-mehr-teilnehmen”
,然后用我将传递给xslt转换器的第二个值替换它的
同级(在本例中是
“停止参与”


我认为这应该很容易,但不幸的是,我没有足够的xslt经验来独自解决这个问题。感谢您的帮助。

如果您能够使用XSLT 2.0或更高版本,以下方法将起作用。XSLT1.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="'&#xD;&#xA;'"/>

    <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('&quot;', current(), '&quot;'))][1], '&quot; = &quot;')"/>

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

出现了各种各样的问题。是否每个源语言字符串都是唯一的?或者,同一源语言字符串是否可以在多个不同的位置多次出现,甚至可能出现在不同的目标语言字符串中?此外,文本文件中的字符串是否可以包含引号,如果是,它们是否被转义?另外,我对您的工作流程很好奇。XLIFF是本地化数据的行业标准文件格式,目前大多数CAT工具都支持XLIFF进行直接处理。您的工作流程是什么,这样您的XLIFF既有
又有
中的源文本,而且您的实际本地化数据存储在一些单独的文本格式中?每个源语言字符串可以出现多次,也需要多次替换。引号确实会出现,所有的转义都是这样的
\“string\”
@EiríkrÚtlendi问题是,在XLIFF之前,Xcode只使用了常用的属性文件(例如en.strings)。我们在这些文件中已经有了这些英文翻译,但是当xcode生成新的XLIFF文件时,它不会处理那些.strings文件中已经存在的翻译。因此,我需要将所有从.strings到.xliff的翻译在最好的情况下只移动一次源-目标字符串是否都是一对一匹配的?或者一个源字符串可以等同于多个不同的目标字符串吗?感谢您宝贵的输入,但不幸的是,我得到的只是一个空结果:-(.strings文件中的翻译都以分号结尾(抱歉,忘了提及这一点),所以我将换行变量替换为:``。另外,我不知道是否正确调用了xslt。我现在正在使用Oxygen XML编辑器。好的,现在它工作了。但是我发现它搜索
标记中的键。这现在可以工作了,但是您是否有一个解决方案,让脚本在
标记中查找内容>
标记,然后用新字符串替换
标记?@gasparuff,您的示例输入XML在
元素中都有源文本。如果您的示例输入XML是工作数据的准确表示,我们就不需要查看
元素的内容,因为源代码xt已经存在于input
元素中。我们只需要将
中的源文本替换为文本文件中的目标文本。如果您的示例输入XML有误导性,则这是另一个问题。:)您是对的,您的答案是正确的:-)。虽然我没有想到字符串文件中的一个翻译被更改,而xliff文件需要更新。这实际上永远不会发生,但我仍然很想知道这样的事情是怎么做的,也许将来有一天我会需要它:D
<?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="'&#xD;&#xA;'"/>

    <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('&quot;', current(), '&quot;'))][1], '&quot; = &quot;')"/>

            <!-- 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>
        <xsl:variable name="target-string" select="substring-after(tokenize($transfile, $newline)
            [contains(., concat('&quot;', current()/../source, '&quot;'))][1], '&quot; = &quot;')"/>
        <!-- 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. -->