0

我在 XSLT 方面缺乏经验,需要帮助解决我用于 XML 转换解决方案的 for-each-group 循环中的一个奇怪错误。这是 XSLT:

<xsl:stylesheet version="2.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:copy-of select="./@*"/>
      <xsl:for-each-group select="node()" group-starting-with="mrk">
        <mrk>
          <xsl:for-each select="current-group()">
            <xsl:choose>
              <xsl:when test="name() = 'mrk' and position() = 1">
                <xsl:copy-of select="./@*"/>
              </xsl:when>
              <xsl:when test="name() != 'mrk'">
                <xsl:copy>
                  <xsl:copy-of select="@* | node()"/>
                </xsl:copy> 
              </xsl:when>         
            </xsl:choose>
          </xsl:for-each>
        </mrk>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

mrk基本思想是将父节点内的空节点后的兄弟target节点移回mrk节点内。使用以下简化的示例输入:

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

我得到这个输出:

<body>
  <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>
        </mrk>
       <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>
</body>

预期输出如下:

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

如何摆脱节点中虚假的第一个空子mrk节点target?我尝试将 for-each-group 选择更改为“*”,但随后我丢失了文本节点。如果有更好的方法可以完全做到这一点,我会全力以赴!:-)

4

1 回答 1

2

我认为这是因为您在node()上的分组正在获取目标元素中第一个mrk元素之前的空白。

在这种情况下,您可以告诉 XSLT 处理器去除这些空间。尝试将以下行添加到 XSLT 的顶部(就在xsl:output之后:

<xsl:strip-space elements="target" />

或者,如果您想对所有元素执行此操作,请执行此操作

<xsl:strip-space elements="*" />

这样做会产生以下输出

<body>
   <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 mid="1" mtype="seg">You can add descriptive text notes to a call recording, if you have the appropriate privileges to do so.</mrk>
         <mrk mid="2" mtype="seg">These notes are visible to all users who have access to the call recording.</mrk>
         <mrk mid="3" mtype="seg">It is recommended that each user add their initials to the notes to avoid potential confusion.</mrk>
      </seg-source>
      <target state="final">
         <mrk mid="1" mtype="seg">
            <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 mid="2" mtype="seg">������������ �������������� ���������� ���������������� �������� ������ ������������������ ���������� ��������.
        </mrk>
         <mrk mid="3" mtype="seg">�������� <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 mid="4" mtype="seg">���������� ������������ �������������������� ���������� ������������ ���� ������������������ �� �������� ������������.
      </mrk>
      </target>
   </trans-unit>
</body>

(抱歉,我的 XSLT 处理器目前正在丢失花哨的文本字符!)

顺便说一句,虽然它不会导致问题,但您实际上可以简化以下语句

 <xsl:when test="name() = 'mrk' and position() = 1">

因为你是从mrk元素开始分组的,所以你只会在位置 1 获得mrk元素,所以你可以这样做

 <xsl:when test="name() = 'mrk'>

(这也意味着另一个xsl:when可以变成xsl:otherwise

于 2013-01-22T11:21:18.390 回答