我在XSLT方面缺乏经验,需要帮助纠正我用于XML转换解决方案的for-each-group循环中的一个奇怪的bug。下面是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>怎样才能去掉target节点中第一个虚假的空mrk子节点?我尝试将for-each-group select更改为"*",但随后丢失了文本节点。如果有更好的方法来完成这一切,我洗耳恭听!:-)
发布于 2013-01-22 19:21:18
我认为这是因为您对节点()的分组正在拾取目标元素中第一个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时
https://stackoverflow.com/questions/14456960
复制相似问题