嗨,我的xml中有重复的节点名,希望每个节点都是唯一的。由于节点数量未知,我想实现一个for each循环,并使用XSLT为每个UserGroup节点的名称添加一个计数器。
我正在使用:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
我的输入xml是:
<groups>
<UserGroup>
<integrationKey>xxa</integrationKey>
<uid>001</uid>]
</UserGroup>
<UserGroup>
<integrationKey>xxb</integrationKey>
<uid>002</uid>
</UserGroup>
</groups>
如何使用XSLT将xml转换为:
<groups>
<UserGroup1>
<integrationKey>xxa</integrationKey>
<uid>001</uid>]
</UserGroup1>
<UserGroup2>
<integrationKey>xxb</integrationKey>
<uid>002</uid>
</UserGroup2>
</groups>
EDIT嗨,原因是我正在处理一个xml消息负载,该负载已建立,然后需要转换为JSON(groups部分附加到主xml(。有效载荷将要到达的目标系统接受某个"有效载荷";格式";不包括UserGroup。不幸的是,UserGroups的数量是动态的,映射的控制有限。我尝试在Groovy中使用构建Json
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import groovy.json.JsonBuilder
def body = """
{"B2BCustomer":{"integrationKey":"","customerID":"xxx","email":"xxx","name":"xxx","uid":"xxx","businessUnit":{"BU":{"integrationKey":"","code":"xxx"}},"groups":[{"UserGroup":{"integrationKey":"xxx","uid":"xxx"},"UserGroup":{"integrationKey":"yyy","uid":"yyy"}}]}}"""
//Setup output JSON
def jsonParser = new JsonSlurper();
def jsonObject = jsonParser.parseText(body);
body = JsonOutput.toJson(jsonObject["B2BCustomer"]);
output = jsonParser.parseText(body);
jsonString = jsonParser.parseText(body);
//Create default b2b unit JSON
if(output.containsKey("defaultB2BUnit")){
output.remove("defaultB2BUnit");
defaultB2BUnit = JsonOutput.toJson(jsonString["defaultB2BUnit"]);
jsonObject = jsonParser.parseText(defaultB2BUnit);
defaultB2BUnit = JsonOutput.toJson(jsonObject["B2BUnit"]);
output.put("defaultB2BUnit", defaultB2BUnit);
}
//Create businessUnit JSON
if(output.containsKey("businessUnit")){
output.remove("businessUnit");
businessUnit = JsonOutput.toJson(jsonString["businessUnit"]);
jsonObject = jsonParser.parseText(businessUnit);
businessUnit = JsonOutput.toJson(jsonObject["BU"]);
output.put("businessUnit", businessUnit);
}
//Create groups JSON
if(output.containsKey("groups")){
output.remove("groups");
groups = JsonOutput.toJson(jsonString["groups"]);
jsonObject = jsonParser.parseText(groups);
groups = JsonOutput.toJson(jsonObject["UserGroup"]);
output.put("groups", groups);
}
//Build output JSON
def builder = new JsonBuilder();
builder(output);
def builderString = builder.toString().replace('"{\', '{').replace('\','').replace('}"','}').replace('"[','[').replace(']"',']');
println builderString;
如果密钥不重复(它只提取一个UserGroup。我的计划是仍然运行此代码,但组组成一个循环以获得所需的JSON输出。
如果有人有办法,我不必做字符串替换,那也太棒了。不幸的是,我无法更改目标系统元数据的结构。
电流输出:
{
"integrationKey": "",
"customerID": "xxx",
"email": "xxx",
"name": "xxx",
"uid": "xxx",
"businessUnit": {
"integrationKey": "",
"code": "xxx"
},
"groups": [{
"integrationKey": "yyy",
"uid": "yyy"
}
]
}
期望输出:
{
"integrationKey": "",
"customerID": "xxx",
"email": "xxx",
"name": "xxx",
"uid": "xxx",
"businessUnit": {
"integrationKey": "",
"code": "xxx"
},
"groups": [{
"integrationKey": "xxx",
"uid": "xxx"
},
{
"integrationKey": "yyy",
"uid": "yyy"
}
]
}
额外注意我正在考虑将组存储在exhange属性中,并运行自定义xml->Json Groovy脚本可以按照我想要的方式构建它,而不会受到Json诽谤等的奇怪影响。感谢您的努力和提前提出的建议!
给定XSLT3,一种方法是使用累加器:
<xsl:accumulator name="UserGroupCounter" as="xs:integer" initial-value="0">
<xsl:accumulator-rule match="groups" select="0"/>
<xsl:accumulator-rule match="groups/UserGroup" select="$value + 1"/>
</xsl:accumulator>
<xsl:template match="UserGroup">
<xsl:element name="{name()}{accumulator-before('UserGroupCounter')}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:mode on-no-match="shallow-copy" use-accumulators="UserGroupCounter"/>
我同意关于结果格式不是一个好的XML格式的评论。如果您需要一些元素索引,通常的建议是不要将其放入元素名称中,而是使用属性,例如
<xsl:accumulator name="UserGroupCounter" as="xs:integer" initial-value="0">
<xsl:accumulator-rule match="groups" select="0"/>
<xsl:accumulator-rule match="groups/UserGroup" select="$value + 1"/>
</xsl:accumulator>
<xsl:template match="UserGroup">
<xsl:copy>
<xsl:attribute name="userGroupIndex" select="accumulator-before('UserGroupCounter')"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:mode on-no-match="shallow-copy" use-accumulators="UserGroupCounter"/>