【问题标题】:XSLT: move sibling text node into selected node for XLIFF fixXSLT:将同级文本节点移动到选定节点以进行 XLIFF 修复
【发布时间】:2023-03-28 10:54:01
【问题描述】:

在对 XSLT 进行了几个小时的研究之后,我承认失败了!我需要修复大量从未命名的翻译工具返回给我们的 .xlf XLIFF 翻译文件。理想情况下,我会使用批处理工具将 XSL 转换应用于它们。

以下是其中一个 XLIFF 文件的 sn-p:

<body>
    <trans-unit id="1" phase-name="pretrans" restype="x-h3">
        <source>Adding, Deleting or Modifying Notes in the Call Description</source>
        <seg-source>Adding, Deleting or Modifying Notes in the Call Description</seg-source>
        <target state="final">Добавление, удаление и изменение примечаний в описании звонка</target>
    </trans-unit>
    <trans-unit id="2" phase-name="pretrans" restype="x-p">
        <source>Description of Fields on RHS</source>
        <seg-source>Description of Fields on RHS</seg-source>
        <target state="final">Поле описания в правой части</target>
    </trans-unit>
    <trans-unit id="3" phase-name="pretrans" restype="x-p">
        <source>You can add descriptive text notes to a call recording, if you have the appropriate privileges to do so. These notes are visible to all users who have access to the call recording. It is recommended that each user add their initials to the notes to avoid potential confusion.</source>
        <seg-source>
            <mrk mtype="seg" mid="1">You can add descriptive text notes to a call recording, if you have the appropriate privileges to do so.</mrk>
            <mrk mtype="seg" mid="2">These notes are visible to all users who have access to the call recording.</mrk>
            <mrk mtype="seg" mid="3">It is recommended that each user add their initials to the notes to avoid potential confusion.</mrk>
        </seg-source>
        <target state="final">
          <mrk mtype="seg" mid="1" /><ph ctype="" id="1">&lt;MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /&gt;</ph> позволяет находить телефонные взаимодействия, содержащие или не содержащие определенные фразы.
          <mrk mtype="seg" mid="2" />Каждая речевая метка содержит одну или несколько таких фраз.
          <mrk mtype="seg" mid="3" />Ядро <ph ctype="" id="3">&lt;MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /&gt;</ph> индексирует медиафайлы и помечает места вхождения фразы (добавляет к ним метки).
          <mrk mtype="seg" mid="4" />Затем нужные медиафайлы можно искать по связанным с ними меткам.
        </target>
    </trans-unit>
    <trans-unit id="4" phase-name="pretrans" restype="x-p">
        <source>To add, delete, or modify text in the description field, click inside the description field.</source>
        <seg-source>To add, delete, or modify text in the description field, click inside the description field.</seg-source>
        <target state="final">Чтобы добавить, удалить или изменить текст в поле описания, щелкните это поле.</target>
    </trans-unit>
</body>

注意第三个trans-unit 节点中的target 标记。 mrk 标签应该包含现在已经成为兄弟的文本节点(与之前的 seg-source 标签相比,这仍然是正确的),从而破坏了结构。

因此,我试图识别任何不包含文本节点的mrk 标签,并将以下文本节点移回其中。

这是想要的结果:

<body>
    <trans-unit id="1" phase-name="pretrans" restype="x-h3">
        <source>Adding, Deleting or Modifying Notes in the Call Description</source>
        <seg-source>Adding, Deleting or Modifying Notes in the Call Description</seg-source>
        <target state="final">Добавление, удаление и изменение примечаний в описании звонка</target>
    </trans-unit>
    <trans-unit id="2" phase-name="pretrans" restype="x-p">
        <source>Description of Fields on RHS</source>
        <seg-source>Description of Fields on RHS</seg-source>
        <target state="final">Поле описания в правой части</target>
    </trans-unit>
    <trans-unit id="3" phase-name="pretrans" restype="x-p">
        <source>You can add descriptive text notes to a call recording, if you have the appropriate privileges to do so. These notes are visible to all users who have access to the call recording. It is recommended that each user add their initials to the notes to avoid potential confusion.</source>
        <seg-source>
            <mrk mtype="seg" mid="1">You can add descriptive text notes to a call recording, if you have the appropriate privileges to do so.</mrk>
            <mrk mtype="seg" mid="2">These notes are visible to all users who have access to the call recording.</mrk>
            <mrk mtype="seg" mid="3">It is recommended that each user add their initials to the notes to avoid potential confusion.</mrk>
        </seg-source>
        <target state="final">
            <mrk mtype="seg" mid="1"><ph ctype="" id="1">&lt;MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /&gt;</ph> позволяет находить телефонные взаимодействия, содержащие или не содержащие определенные фразы.</mrk>
            <mrk mtype="seg" mid="2">Каждая речевая метка содержит одну или несколько таких фраз.</mrk>
            <mrk mtype="seg" mid="3">Ядро <ph ctype="" id="3">&lt;MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /&gt;</ph> индексирует медиафайлы и помечает места вхождения фразы (добавляет к ним метки).</mrk>
            <mrk mtype="seg" mid="4">Затем нужные медиафайлы можно искать по связанным с ними меткам.</mrk>
        </target>
    </trans-unit>
    <trans-unit id="4" phase-name="pretrans" restype="x-p">
        <source>To add, delete, or modify text in the description field, click inside the description field.</source>
        <seg-source>To add, delete, or modify text in the description field, click inside the description field.</seg-source>
        <target state="final">Чтобы добавить, удалить или изменить текст в поле описания, щелкните это поле.</target>
    </trans-unit>
</body>

我通常会在 Perl 中使用 LibXML 或类似工具执行此操作,但我确信这对于 XSLT 来说是一项简单的任务。我已经搜索了类似的解决方案,但找不到任何可以解决的问题。

还有一点需要注意 - 虽然这里“打印得很漂亮”,但最终的 body 节点定义都在一行上。

谢谢!我期待学习新的东西!

编辑:更新了上面的源代码以在&lt;target&gt; 元素中显示更多子标签,这些标签必须保留。 编辑 2:添加了所需的结果。

【问题讨论】:

    标签: xml xslt xpath xliff


    【解决方案1】:

    试试这个 XSLT:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="trans-unit/target/mrk[following-sibling::text()]">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
          <xsl:value-of select="following-sibling::text()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="trans-unit/target/text()"/>
    
    </xsl:stylesheet>
    

    可能会产生预期的结果:

    <body>
        <trans-unit id="1" phase-name="pretrans" restype="x-h3">
            <source>Adding, Deleting or Modifying Notes in the Call Description</source>
            <seg-source>Adding, Deleting or Modifying Notes in the Call Description</seg-source>
            <target state="final" />
        </trans-unit>
        <trans-unit id="2" phase-name="pretrans" restype="x-p">
            <source>Description of Fields on RHS</source>
            <seg-source>Description of Fields on RHS</seg-source>
            <target state="final" />
        </trans-unit>
        <trans-unit id="3" phase-name="pretrans" restype="x-p">
            <source>You can add descriptive text notes to a call recording, if you have the appropriate privileges to do so. These notes are visible to all users who have access to the call recording. It is recommended that each user add their initials to the notes to avoid potential confusion.</source>
            <seg-source>
                <mrk mtype="seg" mid="1">You can add descriptive text notes to a call recording, if you have the appropriate privileges to do so.</mrk>
                <mrk mtype="seg" mid="2">These notes are visible to all users who have access to the call recording.</mrk>
                <mrk mtype="seg" mid="3">It is recommended that each user add their initials to the notes to avoid potential confusion.</mrk>
            </seg-source>
            <target state="final"><mrk mtype="seg" mid="1">При наличии соответствующих прав можно добавить описательные текстовые примечания к записи звонка.
                </mrk><mrk mtype="seg" mid="2">Эти примечания видны для всех пользователей, которые имеют доступ к записи звонка.
                </mrk><mrk mtype="seg" mid="3">Во избежание возможной путаницы каждому пользователю рекомендуется к примечаниям добавлять свои инициалы.
            </mrk></target>
        </trans-unit>
        <trans-unit id="4" phase-name="pretrans" restype="x-p">
            <source>To add, delete, or modify text in the description field, click inside the description field.</source>
            <seg-source>To add, delete, or modify text in the description field, click inside the description field.</seg-source>
            <target state="final" />
        </trans-unit>
    </body>
    

    【讨论】:

    • 你测试过这个吗?除了输出将在文本之后包含额外的空格(包括换行符)之外,它将起作用,这可能是不可接受的。此外,任何 正确 结构的 target/mrk 标记也将通过将mrk 间的空格移动到文本节点中来进行修改。明智地使用normalize-space 应该可以解决问题。
    • @JimGarrison,我提供了准确的输出。无论如何,OP 可以使用normalize-space 函数。
    • @JimGarrison,它不会修改正确的target/mrk。仅包含以下兄弟文本节点的那些。
    • 根据我在 OxygenXML 中的测试,它修改了正确和不正确的 target/mrk(在提供的输入中没有不正确的示例)并包括来自下一行的尾随换行符和缩进空格(部分相同的文本节点)。您有一个结构良好的解决方案,只需稍作调整即可 100% 正确。 +1
    • 我建议将这个:following-sibling::text() 改为这个:following-sibling::node()[1]/self::text()。这样可以确保只抓取每个 &lt;mrk&gt; 之后的文本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多