我有这样的XML:
<object>
<string name "order">1<string>
<string name "item">1<string>
</object>
<object>
<string name "order">1<string>
<string name "item">2<string>
</object>
<object>
<string name "order">2<string>
<string name "item">1<string>
</object>
我想将xml转换为这个结构:
<object order=1>
<string name "item">1<string>
<string name "item">2<string>
</object>
<object order=2>
<string name "item">1<string>
</object>
我想用XSLT动态转换输入XML,但我无法做到这一点 .
1 回答
首先要做的是将源XML格式化为适当的形式 .
XML文档包含 only one 根标记(让我们称之为主标记),此标记可以包含多个源标记(例如对象) .
每个标记(如您在字符串标记中所写)可以包含具有值的属性(在您的情况下为名称和顺序),但它们之间必须是"="符号 .
在对象标记的情况下,您记得在结束标记中放置"/",但是在每个结束字符串标记中都忘记了它 .
因此,正确的输入XML(在需要更正之后)是:
现在让我们来看看主要业务 . 在描述中我放了行号 - 对最终解决方案的引用 .
我们从xsl:output indent = "yes"(第2行)开始,否则所有内容都将在一行中(难以阅读) .
XML代码包含单个模板匹配主标记(第4行) .
它首先要做的是复制(打开和关闭主标签 - 第5行) .
然后,第6行包含分组循环(for-each-group) . 分组的对象是对象元素(请参阅select子句),分组键是字符串子标记(相对于当前对象)的内容,其属性名称等于"order"(请参阅分组子句) .
因此第一组包含对象标记No 1和2(它们都具有字符串名称= "order"标记,内容为"1",第二组包含对象标记No 3 .
然后(对于每组源对象标签),我们创建一个输出对象元素(第7行) .
此元素必须具有名为order的属性,其中包含当前分组键的值(第8行) .
当前元素(输出对象)将包含当前组中每个元素的数据,因此我们必须编写for-each语句,循环遍历所有源对象标记 - 当前组的内容(请参阅select子句,第9行) .
在这个循环中,对于每个输入对象,我们创建一个字符串元素(第10行) .
此元素具有名为"name"的属性(请参阅name子句),其值应为"item"(请参阅select子句) - 第11行 .
最后要做的是创建输出标记的内容 - 子字符串标记(相对于当前对象)的值,名称属性为项值 - 第12行 .
XSL中的所有其他行都是结束标记 .
下面是一个完整的XSL解决方案 .