按顺序转换XML节点
XML输入:按顺序转换XML节点,xml,xslt,Xml,Xslt,XML输入: <a> <b>text_b</b> <d>text_d</d> <c>text_c</c> <e>text_e</e> <d>text_d</d> <f>text_f</f> </a> <g> <b>text_b</b>
<a>
<b>text_b</b>
<d>text_d</d>
<c>text_c</c>
<e>text_e</e>
<d>text_d</d>
<f>text_f</f>
</a>
<g>
<b>text_b</b>
<d>text_d</d>
<c>text_c</c>
<e>text_e</e>
<d>text_d</d>
<f>text_f</f>
</g>
期望输出:
<aa>
<aaa>
<some_extra_tag>some_text</some_extra_tag>
<aab>text_b</aab>
</aaa>
<aad>text_d</aad>
<aaa>
<some_extra_tag>some_text</some_extra_tag>
<aac>text_c</aac>
<aae>text_e</aae>
</aaa>
<aad>text_d</aad>
<aaa>
<some_extra_tag>some_text</some_extra_tag>
<aaf>text_f</aaf>
</aaa>
</aa>
<gg>
<aab>text_b</aab>
<ggg>
<some_extra_tag2>some_text</some_extra_tag2>
<aad>text_d</aad>
</ggg>
<aac>text_c</aac>
<aae>text_e</aae>
<ggg>
<some_extra_tag2>some_text</some_extra_tag2>
<aad>text_d</aad>
</ggg>
<aaf>text_f</aaf>
</gg>
我可以使用XSLT将上述XML输入转换为所需的输出吗?
限制:
一些额外的标签应该由a-tag-Template生成,一些额外的标签2-tag应该由g-tag-Template生成。XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="outer">
<doc>
<xsl:apply-templates select="*" />
</doc>
</xsl:template>
<xsl:template match="*">
<outer>
<span>
<xsl:copy-of select="."/>
</span>
</outer>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="utf-8"?>
<doc>
<outer>
<span>
<inner>text first</inner>
</span>
</outer>
<outer>
<span>
<middle>text second</middle>
</span>
</outer>
<outer>
<span>
<inner>text third</inner>
</span>
</outer>
</doc>
我认为你想做的有点棘手,但我相信下面的内容可以做到。它通过使用递归模板工作:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- standard identity template -->
<xsl:template match="node() | @*" name="Copy">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="outer">
<xsl:copy>
<xsl:apply-templates select="*[not(self::inner)] |
inner[not(preceding-sibling::*[1][self::inner])]" />
</xsl:copy>
</xsl:template>
<xsl:template match="inner[not(preceding-sibling::*[1][self::inner])]">
<span>
<xsl:call-template name="Copy" />
<xsl:apply-templates select="following-sibling::*[1][self::inner]" />
</span>
</xsl:template>
<xsl:template match="inner">
<xsl:call-template name="Copy" />
<xsl:apply-templates select="following-sibling::*[1][self::inner]" />
</xsl:template>
</xsl:stylesheet>
在该输入上运行时:
<outer>
<inner>text first</inner>
<inner>text second</inner>
<middle>text third</middle>
<inner>text fourth</inner>
</outer>
它会产生以下结果:
<outer>
<span>
<inner>text first</inner>
<inner>text second</inner>
</span>
<middle>text third</middle>
<span>
<inner>text fourth</inner>
</span>
</outer>
你是说你想把每个内部和中间部分放在它自己的外部元素中,把内部部分放在跨度内?你还没有真正解释你想做什么。我想做的实际上只是保持原来的顺序,我知道如果我使用,将保持顺序,但是我不能这样做,因为是在外部模板上生成的。实际上,中间标记是否有自己的外部标记并不重要。为了澄清,我有一个编辑我的问题。你的问题仍然不清楚。这个例子模棱两可-转换的规则是什么?@michael.hor257k现在足够清楚了吗?很抱歉,问题始终不够清楚,因为我真的不想包含详细信息。您的输出既不匹配当前请求的输出,也不匹配原始请求的输出。为什么?我的输出有什么问题?为使XML有效而添加的Doc标记,似乎有一些错误,我确实提到需要在外部标记上生成span标记,对吗?@sstept当我的XSLT生成您在所需输出下列出的输出时。如果您想要的输出是其他内容,请澄清并解释您的要求。是的,它确实产生了正确的输出,但是它忽略了我的要求我已经编辑了我的question@sstephen我需要通过外部标记生成span标记是什么意思?你能提供一个我的解决方案不能产生所需结果的输入和输出吗?请更仔细地阅读我的问题,我已经为它写了一个简单的例子,即在下面,比如:。我想我把问题简化了,这是我的要求,而你的答案不合适的情况:在内部标签旁边有inner2标签,它们都需要在同一个跨度标签内。。。文本文本。。。