我对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"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></ph> позволяет находить телефонные взаимодействия, содержащие или не содержащие определенные фразы.
<mrk mtype="seg" mid="2" />Каждая речевая метка содержит одну или несколько таких фраз.
<mrk mtype="seg" mid="3" />Ядро <ph ctype="" id="3"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></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"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></ph> позволяет находить телефонные взаимодействия, содержащие или не содержащие определенные фразы.
</mrk>
<mrk mtype="seg" mid="2">Каждая речевая метка содержит одну или несколько таких фраз.
</mrk>
<mrk mtype="seg" mid="3">Ядро <ph ctype="" id="3"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></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"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></ph> позволяет находить телефонные взаимодействия, содержащие или не содержащие определенные фразы.</mrk>
<mrk mtype="seg" mid="2">Каждая речевая метка содержит одну или несколько таких фраз.</mrk>
<mrk mtype="seg" mid="3">Ядро <ph ctype="" id="3"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></ph> индексирует медиафайлы и помечает места вхождения фразы (добавляет к ним метки).</mrk>
<mrk mtype="seg" mid="4">Затем нужные медиафайлы можно искать по связанным с ними меткам.</mrk>
</target>
</trans-unit>
</body>
如何摆脱mrk
节点中虚假的第一个空target
子节点?我已经尝试将for-each-group选项更改为“*”,但之后我丢失了文本节点。如果有一个更好的方法来完成这个,我全都耳朵! : - )
答案 0 :(得分: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"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></ph> ������������������ ���������������� �������������������� ����������������������������, �������������������� ������ ���� �������������������� ������������������������ ����������.
</mrk>
<mrk mid="2" mtype="seg">������������ �������������� ���������� ���������������� �������� ������ ������������������ ���������� ��������.
</mrk>
<mrk mid="3" mtype="seg">�������� <ph ctype="" id="3"><MadCap:variable name="zoom_userdocs_variables.var_product_name" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" /></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:当可以成为 xsl:否则)