你如何在 Mule 4 中将 SQL 服务器 SELECT 转换为 XML?
How do you convert SQL Server SELECT into XML in Mule 4?
如何在 Mule 4 中使用 Dataweave 将以下 SQL 输出转换为 XML?
SELECT s.RefId
,s.LocalId
,s.StateProvinceId
,s.SchoolName
,e.Email
,e.EmailType
FROM SchoolInfo s
LEFT OUTER JOIN SchoolEmail e
ON e.SchoolRefId = s.RefId
WHERE s.RefId = :ref_id
SQL中的输出是:
RefId LocalId StateProvinceId SchoolName Email Type
7FDF722B-6BBA-4BF0-8205-A5380B269EF1 1 SA Steve's School steven@gmail.com prm
7FDF722B-6BBA-4BF0-8205-A5380B269EF1 1 SA Steve's School test@gmail.com sec
XML 输出应如下所示:
<ns0:SchoolInfo xmlns:ns0="http://www.sifassociation.org/datamodel/au/3.4" RefId="7FDF722B-6BBA-4BF0-8205-A5380B269EF1">
<ns0:LocalId>1</ns0:LocalId>
<ns0:StateProvinceId>SA</ns0:StateProvinceId>
<ns0:SchoolName>Steve's School</ns0:SchoolName>
<ns0:SchoolEmailList>
<ns0:Email Type="prm">steven@gmail.com</ns0:Email>
<ns0:Email Type="sec">test@gmail.com</ns0:Email>
</ns0:SchoolEmailList>
</ns0:SchoolInfo>
谢谢,
史蒂夫
只是跟进我上面的评论。整个解决方案通过 T-SQL.
SQL
-- DDL and sample data population, start
DECLARE @SchoolInfo TABLE
(
RefId VARCHAR(40) PRIMARY KEY,
LocalId INT,
StateProvinceId CHAR(2),
SchoolName VARCHAR(30)
);
DECLARE @SchoolEmail TABLE
(
ID INT PRIMARY KEY,
RefId VARCHAR(40),
Email VARCHAR(30),
EmailType CHAR(3)
);
INSERT @SchoolInfo (RefId, LocalId, StateProvinceId, SchoolName) VALUES
('7FDF722B-6BBA-4BF0-8205-A5380B269EF1', 1, 'CA', 'Steve''s School');
INSERT INTO @SchoolEmail (ID, RefId, Email, EmailType) VALUES
(1, '7FDF722B-6BBA-4BF0-8205-A5380B269EF1', 'steven@gmail.com', 'prm')
,(2, '7FDF722B-6BBA-4BF0-8205-A5380B269EF1', 'test@gmail.com ', 'sec');
-- DDL and sample data population, end
DECLARE @ref_id VARCHAR(40) = '7FDF722B-6BBA-4BF0-8205-A5380B269EF1';
;WITH xmlnamespaces ('http://www.sifassociation.org/datamodel/au/3.4' AS ns0)
SELECT s.RefId AS [@RefId]
, s.LocalId AS [ns0:LocalId]
, s.StateProvinceId AS [ns0:StateProvinceId]
, s.SchoolName AS [ns0:SchoolName]
, (
SELECT e.EmailType AS [ns0:Email/@Type]
, e.Email AS [ns0:Email]
FROM @SchoolEmail AS e
WHERE e.RefId = s.RefId
FOR XML PATH(''), TYPE, ROOT('ns0:SchoolEmailList')
)
FROM @SchoolInfo AS s
WHERE s.RefId = @ref_id
FOR XML PATH('ns0:SchoolInfo'), TYPE;
Output
<ns0:SchoolInfo xmlns:ns0="http://www.sifassociation.org/datamodel/au/3.4" RefId="7FDF722B-6BBA-4BF0-8205-A5380B269EF1">
<ns0:LocalId>1</ns0:LocalId>
<ns0:StateProvinceId>CA</ns0:StateProvinceId>
<ns0:SchoolName>Steve's School</ns0:SchoolName>
<ns0:SchoolEmailList xmlns:ns0="http://www.sifassociation.org/datamodel/au/3.4">
<ns0:Email Type="prm">steven@gmail.com</ns0:Email>
<ns0:Email Type="sec">test@gmail.com </ns0:Email>
</ns0:SchoolEmailList>
</ns0:SchoolInfo>
这是将生成相同内容的 DW 表达式 XML:
%dw 2.0
output application/xml
ns ns0 http://www.sifassociation.org/datamodel/au/3.4
var rId = payload[0].RefId
var lId = payload[0].LocalId
var sId = payload[0].StateProvinceId
---
ns0#SchoolInfo @(RefId: rId): {
ns0#LocalId: lId,
ns0#StateProvinceId: sId,
ns0#SchoolEmailList: payload reduce (e,acc={}) -> acc ++ {
ns0#Email @(Type: e.Type): e.Email
}
}
我假设 RefId
、LocalId
和 StateProvinceId
每次查询都相同。
reduce
的解释:
reduce
解释为 here in detail along with its theoretical foundations. Here's also reduce
's MuleSoft documentation page。最后一页很好地解释了 reduce
现在用我自己的话说,reduce
将 (1) 数组和 (2) lambda 函数作为输入。
包含元素的数组 reduce
将以与 map
函数类似的方式迭代。 map
和 reduce
函数之间的相似之处到此为止:).
lambda 函数需要两个参数:(1) 从数组迭代的当前元素和 (2) 累加器。累加器可以初始化为一个值(我在你的用例中将它设置为一个对象 {}
因为 XML 不喜欢数组)。此 FIRST 迭代的 lambda 函数的结果被设置为下一次迭代的累加器,依此类推。
reduce
的结果是数组迭代完成后的累加器。
因此,如果我要跟踪这个特定的 reduce
,它将看起来像这样,我简化了这些值的表示:
/*
* 1st iteration: (e=steven@gmail.com, acc={}) -> acc + {Email: steven@gmail.com}
* 2nd iteration: (e=test@gmail.com, acc={Email: steven@gmail.com} -> acc + {Email: test@gmail.com}
* result: acc = {Email: steven@gmail.com, Email: test@gmail.com}
*/
如何在 Mule 4 中使用 Dataweave 将以下 SQL 输出转换为 XML?
SELECT s.RefId
,s.LocalId
,s.StateProvinceId
,s.SchoolName
,e.Email
,e.EmailType
FROM SchoolInfo s
LEFT OUTER JOIN SchoolEmail e
ON e.SchoolRefId = s.RefId
WHERE s.RefId = :ref_id
SQL中的输出是:
RefId LocalId StateProvinceId SchoolName Email Type
7FDF722B-6BBA-4BF0-8205-A5380B269EF1 1 SA Steve's School steven@gmail.com prm
7FDF722B-6BBA-4BF0-8205-A5380B269EF1 1 SA Steve's School test@gmail.com sec
XML 输出应如下所示:
<ns0:SchoolInfo xmlns:ns0="http://www.sifassociation.org/datamodel/au/3.4" RefId="7FDF722B-6BBA-4BF0-8205-A5380B269EF1">
<ns0:LocalId>1</ns0:LocalId>
<ns0:StateProvinceId>SA</ns0:StateProvinceId>
<ns0:SchoolName>Steve's School</ns0:SchoolName>
<ns0:SchoolEmailList>
<ns0:Email Type="prm">steven@gmail.com</ns0:Email>
<ns0:Email Type="sec">test@gmail.com</ns0:Email>
</ns0:SchoolEmailList>
</ns0:SchoolInfo>
谢谢, 史蒂夫
只是跟进我上面的评论。整个解决方案通过 T-SQL.
SQL
-- DDL and sample data population, start
DECLARE @SchoolInfo TABLE
(
RefId VARCHAR(40) PRIMARY KEY,
LocalId INT,
StateProvinceId CHAR(2),
SchoolName VARCHAR(30)
);
DECLARE @SchoolEmail TABLE
(
ID INT PRIMARY KEY,
RefId VARCHAR(40),
Email VARCHAR(30),
EmailType CHAR(3)
);
INSERT @SchoolInfo (RefId, LocalId, StateProvinceId, SchoolName) VALUES
('7FDF722B-6BBA-4BF0-8205-A5380B269EF1', 1, 'CA', 'Steve''s School');
INSERT INTO @SchoolEmail (ID, RefId, Email, EmailType) VALUES
(1, '7FDF722B-6BBA-4BF0-8205-A5380B269EF1', 'steven@gmail.com', 'prm')
,(2, '7FDF722B-6BBA-4BF0-8205-A5380B269EF1', 'test@gmail.com ', 'sec');
-- DDL and sample data population, end
DECLARE @ref_id VARCHAR(40) = '7FDF722B-6BBA-4BF0-8205-A5380B269EF1';
;WITH xmlnamespaces ('http://www.sifassociation.org/datamodel/au/3.4' AS ns0)
SELECT s.RefId AS [@RefId]
, s.LocalId AS [ns0:LocalId]
, s.StateProvinceId AS [ns0:StateProvinceId]
, s.SchoolName AS [ns0:SchoolName]
, (
SELECT e.EmailType AS [ns0:Email/@Type]
, e.Email AS [ns0:Email]
FROM @SchoolEmail AS e
WHERE e.RefId = s.RefId
FOR XML PATH(''), TYPE, ROOT('ns0:SchoolEmailList')
)
FROM @SchoolInfo AS s
WHERE s.RefId = @ref_id
FOR XML PATH('ns0:SchoolInfo'), TYPE;
Output
<ns0:SchoolInfo xmlns:ns0="http://www.sifassociation.org/datamodel/au/3.4" RefId="7FDF722B-6BBA-4BF0-8205-A5380B269EF1">
<ns0:LocalId>1</ns0:LocalId>
<ns0:StateProvinceId>CA</ns0:StateProvinceId>
<ns0:SchoolName>Steve's School</ns0:SchoolName>
<ns0:SchoolEmailList xmlns:ns0="http://www.sifassociation.org/datamodel/au/3.4">
<ns0:Email Type="prm">steven@gmail.com</ns0:Email>
<ns0:Email Type="sec">test@gmail.com </ns0:Email>
</ns0:SchoolEmailList>
</ns0:SchoolInfo>
这是将生成相同内容的 DW 表达式 XML:
%dw 2.0
output application/xml
ns ns0 http://www.sifassociation.org/datamodel/au/3.4
var rId = payload[0].RefId
var lId = payload[0].LocalId
var sId = payload[0].StateProvinceId
---
ns0#SchoolInfo @(RefId: rId): {
ns0#LocalId: lId,
ns0#StateProvinceId: sId,
ns0#SchoolEmailList: payload reduce (e,acc={}) -> acc ++ {
ns0#Email @(Type: e.Type): e.Email
}
}
我假设 RefId
、LocalId
和 StateProvinceId
每次查询都相同。
reduce
的解释:
reduce
解释为 here in detail along with its theoretical foundations. Here's also reduce
's MuleSoft documentation page。最后一页很好地解释了 reduce
现在用我自己的话说,reduce
将 (1) 数组和 (2) lambda 函数作为输入。
包含元素的数组 reduce
将以与 map
函数类似的方式迭代。 map
和 reduce
函数之间的相似之处到此为止:).
lambda 函数需要两个参数:(1) 从数组迭代的当前元素和 (2) 累加器。累加器可以初始化为一个值(我在你的用例中将它设置为一个对象 {}
因为 XML 不喜欢数组)。此 FIRST 迭代的 lambda 函数的结果被设置为下一次迭代的累加器,依此类推。
reduce
的结果是数组迭代完成后的累加器。
因此,如果我要跟踪这个特定的 reduce
,它将看起来像这样,我简化了这些值的表示:
/*
* 1st iteration: (e=steven@gmail.com, acc={}) -> acc + {Email: steven@gmail.com}
* 2nd iteration: (e=test@gmail.com, acc={Email: steven@gmail.com} -> acc + {Email: test@gmail.com}
* result: acc = {Email: steven@gmail.com, Email: test@gmail.com}
*/