我正在尝试找出一个应该相当简单的 xslt,但却让我有些不快。基本上,我想从以下 xml 开始...
<?xml version="1.0" encoding="UTF-8"?>
<TEST>
<OBR>
<OBR-1>obr1</OBR-1>
</OBR>
<OBX>
<OBX-1>obx1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2</OBX-1>
</OBX>
<OBR>
<OBR-1>obr2</OBR-1>
</OBR>
<OBX>
<OBX-1>obx2-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2-2</OBX-1>
</OBX>
<OBR>
<OBR-1>obr3</OBR-1>
</OBR>
<OBX>
<OBX-1>obx3-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx3-2</OBX-1>
</OBX>
</TEST>
最后得到以下...
<?xml version="1.0" encoding="UTF-8"?>
<TEST>
<OBR>
<OBR-1>obr1</OBR-1>
</OBR>
<OBX>
<OBX-1>obx1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2</OBX-1>
</OBX>
<SENSITIVITY>
<OBR>
<OBR-1>obr2</OBR-1>
</OBR>
<OBX>
<OBX-1>obx2-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2-2</OBX-1>
</OBX>
<OBR>
<OBR-1>obr3</OBR-1>
</OBR>
<OBX>
<OBX-1>obx3-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx3-2</OBX-1>
</OBX>
</SENSITIVITY>
</TEST>
基本上,一旦到达第二个 OBR 元素,它以及任何后续的 OBR 和 OBX 都必须包含在 SENSITIVITY 元素中。初始 xml 中可能包含也可能不包含多个 OBR。
谢谢。
最佳答案
这个简单而简短的转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OBR[2]">
<SENSITIVITY>
<xsl:apply-templates select=".|following-sibling::node()" mode="inGroup"/>
</SENSITIVITY>
</xsl:template>
<xsl:template match="node()" mode="inGroup">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="*[count(preceding-sibling::OBR) >1]"/>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<TEST>
<OBR>
<OBR-1>obr1</OBR-1>
</OBR>
<OBX>
<OBX-1>obx1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2</OBX-1>
</OBX>
<OBR>
<OBR-1>obr2</OBR-1>
</OBR>
<OBX>
<OBX-1>obx2-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2-2</OBX-1>
</OBX>
<OBR>
<OBR-1>obr3</OBR-1>
</OBR>
<OBX>
<OBX-1>obx3-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx3-2</OBX-1>
</OBX>
</TEST>
产生想要的、正确的结果:
<TEST>
<OBR>
<OBR-1>obr1</OBR-1>
</OBR>
<OBX>
<OBX-1>obx1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2</OBX-1>
</OBX>
<SENSITIVITY>
<OBR>
<OBR-1>obr2</OBR-1>
</OBR>
<OBX>
<OBX-1>obx2-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx2-2</OBX-1>
</OBX>
<OBR>
<OBR-1>obr3</OBR-1>
</OBR>
<OBX>
<OBX-1>obx3-1</OBX-1>
</OBX>
<OBX>
<OBX-1>obx3-2</OBX-1>
</OBX>
</SENSITIVITY>
</TEST>
解释:
identity rule “按原样”复制每个节点。
模板覆盖
OBR
的身份规则其父元素的第二个元素OBR
child 。这里我们生成包装器元素SENSITIVITY
并在特殊的 mode 中处理所有后续节点,命名为"inGroup"
.匹配
"ingroup"
中任意元素的模板mode 简单地调用身份规则。或者,在这里我们可以简单地使用<xsl:copy-of select="."/>
说明。禁止身份模板将第二个
OBR
之后的元素复制到输出(在正常、匿名模式下) ,我们指定了另一个匹配任何此类元素且主体为空的模板规则,这有效地防止了任何此类元素被复制到输出。此模板覆盖并抑制身份规则。
关于xml - XSLT 根据计数包装后续的同级元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7492605/