这是我要翻译的xml。
<?xml version="1.0" encoding="UTF-8" ?>
<Loop xmlns="http://www.example.org">
<Loop-2000A>
<Element-628>81</Element-628>
<Element-734 nil="nil82"/>
<Element-735>83</Element-735>
<Element-736>84</Element-736>
</Loop-2000A>
<Loop-2000B>
<Element-1035>85</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
</Loop-2000B>
<Loop-2000B>
<Element-1035>98</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
</Loop-2000B>
<Loop-2000C>
<Element-1031>86</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>25</Element-1038>
</Loop-2000C>
<Loop-2000A>
<Element-628>89</Element-628>
<Element-734 nil="nil82"/>
<Element-735>99</Element-735>
<Element-736>109</Element-736>
</Loop-2000A>
<Loop-2000B>
<Element-1035>208</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
</Loop-2000B>
<Loop-2000C>
<Element-1031>92</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>90</Element-1038>
</Loop-2000C>
<Loop-2000B>
<Element-1035>209</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
</Loop-2000B>
</Loop>
要求是...... Loop-2000A的父母...... Loop-2000B ..和Loop-2000B 2000-C的父母。 Loop2000-C在源xml中是可选的。其他循环在xml中的Loop-2000A之外的循环应该按原样进行转换。因此,转换后的XML看起来应该是这样的。
<?xml version = '1.0' encoding = 'UTF-8'?>
<ns2:TargetLoop xmlns:ns2="http://www.target.org">
<Loop-2000A>
<Loop-2000B>
<Element-1035>85</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
</Loop-2000B>
<Loop-2000B>
<Element-1035>98</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
<Loop-2000C>
<Element-1031>86</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>25</Element-1038>
</Loop-2000C>
</Loop-2000B>
<Element-628>81</Element-628>
<Element-734 nil="nil82"/>
<Element-735>83</Element-735>
<Element-736>84</Element-736>
</Loop-2000A>
<Loop-2000A>
<Loop-2000B>
<Element-1035>208</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>87</Element-1037>
<Loop-2000C>
<Element-1031>92</Element-1031>
<Element-1039 nil="nil86"/>
<Element-1038>90</Element-1038>
</Loop-2000C>
</Loop-2000B>
<Loop-2000B>
<Element-1035>209</Element-1035>
<Element-1036 nil="nil86"/>
<Element-1037>97</Element-1037>
</Loop-2000B>
<Element-628>89</Element-628>
<Element-734 nil="nil82"/>
<Element-735>99</Element-735>
<Element-736>109</Element-736>
</Loop-2000A>
</Loop>
任何建议都将不胜感激
答案 0 :(得分:0)
在XSLT 2.0中,您可能使用 group-starting-with 属性来使用 xsl:for-each-group 。但是在XSLT 1.0中,这可以通过使用密钥来实现。您可以定义一个键,通过前面的第一个 Loop-2000A 元素来查找 Loop-2000B 元素
<xsl:key name="B" match="ex:Loop-2000B" use="generate-id(preceding-sibling::ex:Loop-2000A[1])" />
同样地,您可以通过第一个前面的 Loop-2000B 元素将 Loop-2000C 元素关联起来(尽管如果您说可以存在,这可能不是必需的)每个 Loop-2000B最多只有一个 Loop-2000C 元素
<xsl:key name="C" match="ex:Loop-2000C" use="generate-id(preceding-sibling::ex:Loop-2000B[1])" />
generate-id 函数是一个XSLT函数,可用于为每个节点生成唯一的id(如果其中一个现有子元素可以唯一标识该元素,您也可以使用该函数)。请注意,使用 ex:前缀是因为XML中的所有元素都在命名空间中,因此XSLT需要知道哪些命名空间元素。
在您的XSLT中,您只需选择 Loop-2000A 元素即可。
<xsl:apply-templates select="ex:Loop-2000A" />
然后,在匹配 ex:Loop-2000A 的模板中,您可以使用键选择所有关联的 ex:Loop-2000B 元素
<xsl:apply-templates select="key('B', generate-id(current()))" />
您可以采用类似的方法在 ex:Loop-2000B 的模板中获取 ex:Loop-2000C 。虽然,如果最多只有一个这样的 ex:Loop-2000C 元素,你可以这样做而不用担心这种情况下的密钥:
<xsl:apply-templates select="following-sibling::*[1][self::ex:Loop-2000C]" />
这将获得以下兄弟元素,但前提是它是 Loop-2000C 元素。
最后,可以使用Identity Transform
匹配和复制其他现有元素<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ex="http://www.example.org">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:key name="B" match="ex:Loop-2000B" use="generate-id(preceding-sibling::ex:Loop-2000A[1])" />
<xsl:key name="C" match="ex:Loop-2000C" use="generate-id(preceding-sibling::ex:Loop-2000B[1])" />
<xsl:template match="*[ex:Loop-2000A]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="ex:Loop-2000A" />
<xsl:apply-templates select="*[not(self::ex:Loop-2000A)][not(self::ex:Loop-2000B)][not(self::ex:Loop-2000C)]" />
</xsl:copy>
</xsl:template>
<xsl:template match="ex:Loop-2000A">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="key('B', generate-id(current()))" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="ex:Loop-2000B">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="key('C', generate-id(current()))" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>