提问人:user22788171 提问时间:10/23/2023 最后编辑:Mads Hansenuser22788171 更新时间:10/24/2023 访问量:50
用于在父段下插入段的 XSLT 代码
XSLT code to insert segment under parent segment
问:
我有一个输入 XML 文档,其中需要在父段下移动几个段,条件应该在段下仅为“8R”时。对于其他段且没有条件,只需移动到 下即可。<c>
<b>
<b2>
<e>
<f>
<d>
<?xml version="1.0" encoding="UTF-8"?>
<ns0:TEST_Report xmlns:ns0="urn:abc">
<Record>
<a>
<a1>123</a1>
<a2>11</a2>
</a>
<b>
<b1>23</b1>
<b2>SJ</b2>
</b>
<b>
<b1>67</b1>
<b2>8S</b2>
</b>
<b>
<b1>90</b1>
<b2>8R</b2>
</b>
<c>
<c1>asd</c1>
<c2>2342445435346</c2>
</c>
<c>
<c1>wsx</c1>
<c2>8798987978</c2>
</c>
<d>
<d1>XYZ</d1>
<d2>cvb</d2>
</d>
<e>
<e1>1212</e1>
</e>
<e>
<e1>4321</e1>
</e>
<f>
<f1>11</f1>
<f2>11</f2>
</f>
<f>
<f1>133</f1>
<f2>1133</f2>
</f>
<f>
<f1>1345</f1>
<f2>54434</f2>
</f>
<d>
<d1>XYZ</d1>
<d2>cvb</d2>
</d>
<e>
<e1>1212</e1>
</e>
<f>
<f1>11</f1>
<f2>11</f2>
</f>
<f>
<f1>133</f1>
<f2>1133</f2>
</f>
</Record>
</ns0:TEST_Report>
我试过的 XSLT 代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="urn:abc">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="TEST_Report">
<ns0:TEST_Report>
<xsl:apply-templates select="@*|node()"/>
</ns0:TEST_Report>
</xsl:template>
<xsl:template match="B">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="following-sibling::C[1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="C">
<xsl:if test="preceding-sibling::B[3]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
所需输出:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:TEST_Report xmlns:ns0="urn:abc">
<Record>
<a>
<a1>123</a1>
<a2>11</a2>
</a>
<b>
<b1>23</b1>
<b2>SJ</b2>
</b>
<b>
<b1>67</b1>
<b2>8S</b2>
</b>
<b>
<b1>90</b1>
<b2>8R</b2>
<c>
<c1>asd</c1>
<c2>2342445435346</c2>
</c>
<c>
<c1>wsx</c1>
<c2>8798987978</c2>
</c>
</b>
<d>
<d1>XYZ</d1>
<d2>cvb</d2>
<e>
<e1>1212</e1>
</e>
<e>
<e1>4321</e1>
</e>
<f>
<f1>11</f1>
<f2>11</f2>
</f>
<f>
<f1>133</f1>
<f2>1133</f2>
</f>
<f>
<f1>1345</f1>
<f2>54434</f2>
</f>
</d>
<d>
<d1>XYZ</d1>
<d2>cvb</d2>
<e>
<e1>1212</e1>
</e>
<f>
<f1>11</f1>
<f2>11</f2>
</f>
<f>
<f1>133</f1>
<f2>1133</f2>
</f>
</d>
</Record>
</ns0:TEST_Report>
请使用 xslt 1.0 代码帮助实现此目的。我也尝试了其他一些代码,但它不适用于此要求。
答:
0赞
michael.hor257k
10/23/2023
#1
这比看起来要复杂得多 - 不是因为 上的条件,而是因为你有多个元素,每个元素都有自己的 和 元素的“尾巴”。b
d
e
f
从第一个的上下文来看,所有后续元素和元素都在轴上 - 无论沿途放置任何“干预”元素。所以基本上你正在寻找一个 的 XSLT 1.0 实现,它可以被处理为:d
e
f
following-sibling
d
group-starting-with
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="c" match="c" use="generate-id(preceding-sibling::b[b2='8R'][1])" />
<xsl:key name="ef" match="e|f" use="generate-id(preceding-sibling::d[1])" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="b[b2='8R']">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:copy-of select="key('c', generate-id())"/>
</xsl:copy>
</xsl:template>
<xsl:template match="d">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:copy-of select="key('ef', generate-id())"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c[preceding-sibling::b[1]/b2='8R'] | e | f"/>
</xsl:stylesheet>
如果每个模板都有一个包含 的前面的同级,那么您可以将最后一个模板简化为:c
b
<b2>8R</b2>
<xsl:template match="c|e|f"/>
下一个:XSL 模板不匹配
评论
c
b
<b2>8R</b2>
e
f
d
b
<b2>8R</b2>
b