我得到了一些奇怪的XML,我必须在其他地方导入。结构就像这个例子:
<INVOICE>
<HEADER_DATA_1>
<HEADER_DATA_ITEM_1>foo</HEADER_DATA_ITEM_1>
<HEADER_DATA_ITEM_2>bar</HEADER_DATA_ITEM_2>
</HEADER_DATA_1>
<HEADER_DATA_2>
<HEADER_DATA_ITEM_3>foo</HEADER_DATA_ITEM_3>
<HEADER_DATA_ITEM_4>bar</HEADER_DATA_ITEM_4>
</HEADER_DATA_2>
<HEADER_DATA_3>
<HEADER_DATA_ITEM_5>foo</HEADER_DATA_ITEM_5>
<HEADER_DATA_ITEM_6>bar</HEADER_DATA_ITEM_6>
</HEADER_DATA_3>
<POSITION_DATA_1>
<POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1>
<POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2>
</POSITION_DATA_1>
<POSITION_DATA_2>
<POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3>
<POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4>
</POSITION_DATA_2>
[...]
<POSITION_DATA_8>
<POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15>
<POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16>
</POSITION_DATA_8>
<POSITION_DATA_1>
<POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1>
<POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2>
</POSITION_DATA_1>
<POSITION_DATA_2>
<POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3>
<POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4>
</POSITION_DATA_2>
[...]
<POSITION_DATA_8>
<POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15>
<POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16>
</POSITION_DATA_8>
<POSITION_DATA_1>
<POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1>
<POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2>
</POSITION_DATA_1>
<POSITION_DATA_2>
<POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3>
<POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4>
</POSITION_DATA_2>
[...]
<POSITION_DATA_8>
<POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15>
<POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16>
</POSITION_DATA_8>
</INVOICE>
如您所见,发票objekt可以有一些单一的标题数据和一些多个位置,这些位置包含一些位置数据。但遗憾的是,这些出口的人忘了在位置数据周围包裹一个合适的标签。所以我想修复它,以便最终的代码看起来像这样:
<INVOICE>
<HEADER_DATA_1>
<HEADER_DATA_ITEM_1>foo</HEADER_DATA_ITEM_1>
<HEADER_DATA_ITEM_2>bar</HEADER_DATA_ITEM_2>
</HEADER_DATA_1>
<HEADER_DATA_2>
<HEADER_DATA_ITEM_3>foo</HEADER_DATA_ITEM_3>
<HEADER_DATA_ITEM_4>bar</HEADER_DATA_ITEM_4>
</HEADER_DATA_2>
<HEADER_DATA_3>
<HEADER_DATA_ITEM_5>foo</HEADER_DATA_ITEM_5>
<HEADER_DATA_ITEM_6>bar</HEADER_DATA_ITEM_6>
</HEADER_DATA_3>
<POSITION>
<POSITION_DATA_1>
<POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1>
<POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2>
</POSITION_DATA_1>
<POSITION_DATA_2>
<POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3>
<POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4>
</POSITION_DATA_2>
[...]
<POSITION_DATA_8>
<POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15>
<POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16>
</POSITION_DATA_8>
</POSITION>
<POSITION>
<POSITION_DATA_1>
<POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1>
<POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2>
</POSITION_DATA_1>
<POSITION_DATA_2>
<POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3>
<POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4>
</POSITION_DATA_2>
[...]
<POSITION_DATA_8>
<POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15>
<POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16>
</POSITION_DATA_8>
</POSITION>
<POSITION>
<POSITION_DATA_1>
<POSITION_DATA_ITEM_1>foo</POSITION_DATA_ITEM_1>
<POSITION_DATA_ITEM_2>bar</POSITION_DATA_ITEM_2>
</POSITION_DATA_1>
<POSITION_DATA_2>
<POSITION_DATA_ITEM_3>foo</POSITION_DATA_ITEM_3>
<POSITION_DATA_ITEM_4>bar</POSITION_DATA_ITEM_4>
</POSITION_DATA_2>
[...]
<POSITION_DATA_8>
<POSITION_DATA_ITEM_15>foo</POSITION_DATA_ITEM_15>
<POSITION_DATA_ITEM_16>bar</POSITION_DATA_ITEM_16>
</POSITION_DATA_8>
</POSITION>
</INVOICE>
更糟糕的是,某些元素是可选的,尤其是POSITION_DATA_1元素。至少POSITION_DATA_2和POSITION_DATA_8是强制性的。我修复了(可能)缺少的POSITION_DATA_1标签,如下所示:
<xsl:template name="identity" match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="POSITION_DATA_2[not(preceding-sibling::POSITION_DATA_1)]">
<xsl:element name="POSITION_DATA_1"/>
<xsl:call-template name="identity"/>
</xsl:template>
如果缺少则插入它。为了我的主要目标,我尝试调整this thread的解决方案。我试过的规则看起来像这样:
<xsl:template match="INVOICE">
<xsl:copy>
<xsl:apply-templates select="HEADER_DATA_1|HEADER_DATA_2|HEADER_DATA_3"/>
<POSITION>
<xsl:apply-templates select="POSITION_DATA_1|POSITION_DATA_2|POSITION_DATA_3|POSITION_DATA_4|POSITION_DATA_5|POSITION_DATA_6|POSITION_DATA_7|POSITION_DATA_8"/>
</POSITION>
</xsl:copy>
</xsl:template>
但这不符合。它只包含一个POSITION标签围绕所有位置。有什么建议吗?
答案 0 :(得分:0)
考虑使用密钥按前面POSITION_DATA_2
POSITION_DATA_8
到POSITION_DATA_1
元素进行分组
然后,要在所有项目周围包含一个包含标记,您只需要一个模板POSITION_DATA_1
,然后使用该键来获取所有其他项目。
<xsl:template match="POSITION_DATA_1">
<POSITION>
<xsl:call-template name="identity" />
<xsl:apply-templates select="key('pos', generate-id())" />
</POSITION>
</xsl:template>
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="pos"
match="*[starts-with(local-name(), 'POSITION_DATA_') and not(self::POSITION_DATA_1)]"
use="generate-id(preceding-sibling::POSITION_DATA_1[1])" />
<xsl:template name="identity" match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="INVOICE">
<xsl:copy>
<xsl:apply-templates select="HEADER_DATA_1|HEADER_DATA_2|HEADER_DATA_3"/>
<xsl:apply-templates select="POSITION_DATA_1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="POSITION_DATA_1">
<POSITION>
<xsl:call-template name="identity" />
<xsl:apply-templates select="key('pos', generate-id())" />
</POSITION>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
如果您可以使用XSLT 2.0,那么可以使用位置分组来实现:
DeletemodalComponent
答案 2 :(得分:0)
谢谢你们的好主意! 我终于改编了Michael Kays的答案。现在是时候提出我的最终解决方案了:
<xsl:template match="INVOICE">
<xsl:for-each-group select="*" group-starting-with="POSITION_DATA_1 | POSITION_DATA_2[not(preceding-sibling::POSITION_DATA_1)]">
<xsl:choose>
<!-- Do no wrap the header data group -->
<xsl:when test="starts-with(local-name(), 'HEADER_DATA_1')">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<POSITION>
<xsl:apply-templates select="current-group()"/>
</POSITION>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>