如何解决如何遍历 xslt3.0 中的当前组并打印每个值
[
{
"PERSON_ID": 78,"EFFECTIVE_START_DATE": "2013-12-02 00:00:00","LAST_NAME": "Hulk78"
},{
"PERSON_ID": 78,"EFFECTIVE_START_DATE": "2020-06-24 07:29:26","LAST_NAME": "Hulks78"
},{
"PERSON_ID": 79,"EFFECTIVE_START_DATE": "2015-12-02 00:00:00","LAST_NAME": "Hulk79"
},"EFFECTIVE_START_DATE": "2020-07-24 07:29:26","LAST_NAME": "Hulks79"
},{
"PERSON_ID": 80,"EFFECTIVE_START_DATE": "2013-12-10 00:00:00","LAST_NAME": "Hulk15"
}
]
预期输出
[
{
"PersonId": 78,"value": [
{
"EffectiveDate": "2013-12-02 00:00:00","lastName":"Hulk78"
},{
"EffectiveDate": "2020-06-24 07:29:26","lastName":"Hulks78"
}
]
}
....
]
我想通过对 person_id 值进行分组来转换输入 json,并为每个组在与该人 id 对应的值数组中添加其各自的 EffectiveDate 和 lastname。 下面是我试过的 xslt。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0"
xmlns="http://www.w3.org/2005/xpath-functions" xpath-default-namespace="http://www.w3.org/2005/xpath-functions" expand-text="yes">
<xsl:param name="input"/>
<xsl:output method="text"/>
<xsl:template name="xsl:initial-template">
<xsl:variable name="input-as-xml" select="json-to-xml($input)"/>
<xsl:variable name="transformed-xml" as="element(array)">
<array>
<xsl:for-each-group select="$input-as-xml" group-by="//number[@key='PERSON_ID']">
<map>
<string key="PersonId">
<xsl:value-of select="current-grouping-key()"/>
</string>
<array key="Value">
<xsl:for-each select="current-group()">
<map>
<string key="EffectiveDate">
<xsl:value-of select="../string[@key='EFFECTIVE_START_DATE']"/>
</string>
<string key="LASTNAME">
<xsl:value-of select="@LAST_NAME"/>
</string>
</map>
</xsl:for-each>
</array>
</map>
</xsl:for-each-group>
</array>
</xsl:variable>
<xsl:value-of select="xml-to-json($transformed-xml)"/>
</xsl:template>
谁能帮我理解如何从当前组中取出每个生效日期和姓氏。
这是我得到的输出
[
{
"PersonId": "78","Value": [
{
"EffectiveDate": "","LASTNAME": ""
}
]
},{
"PersonId": "79",{
"PersonId": "80","LASTNAME": ""
}
]
}
]
解决方法
你很接近。这是构建变量的方法:
<xsl:variable name="transformed-xml" as="element()">
<array>
<xsl:for-each-group select="$input-as-xml/array/map" group-by="number[@key='PERSON_ID']">
<map>
<string key="PersonId">
<xsl:value-of select="current-grouping-key()"/>
</string>
<array key="Value">
<xsl:for-each select="current-group()">
<map>
<string key="EffectiveDate">
<xsl:value-of select="string[@key='EFFECTIVE_START_DATE']"/>
</string>
<string key="LASTNAME">
<xsl:value-of select="string[@key='LAST_NAME']"/>
</string>
</map>
</xsl:for-each>
</array>
</map>
</xsl:for-each-group>
</array>
</xsl:variable>
,
请注意,作为替代方法,您还可以将 JSON 直接转换为 XDM 3.1 映射和数组,并对这些数据进行分组,而无需来回转换为 XML;唯一的缺点是 XSLT 3 缺少创建数组的指令,因此您必须依赖 XPath 3.1 表达式,例如 [ ]
或 array { }
,有时需要您在模板中使用函数调用。
您的示例的示例是
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:function name="mf:group" as="map(*)*">
<xsl:param name="persons" as="map(*)*"/>
<xsl:for-each-group select="$persons" group-by="?PERSON_ID">
<xsl:sequence select="map { 'PersonId' : current-grouping-key(),'value' : array {
current-group() ! map { 'EffectiveDate ' : ?EFFECTIVE_START_DATE,'lastName' : ?LAST_NAME } } }"/>
</xsl:for-each-group>
</xsl:function>
<xsl:output method="json" indent="yes"/>
<xsl:param name="json-input" as="xs:string"/>
<xsl:template name="xsl:initial-template">
<xsl:apply-templates select="parse-json($json-input)"/>
</xsl:template>
<xsl:template match=".">
<xsl:sequence select="array { mf:group(?*) }"/>
</xsl:template>
</xsl:stylesheet>
JSON -> XML -> JSON 转换的另一个缺点是 XDM 映射中缺少键值对的顺序,这样序列化的 JSON 通常没有您期望的键顺序。 Saxon 的商业版本有一些扩展属性来定义序列化的顺序。
在 Saxon JS 2.2 及更高版本的 xslt3
中,您甚至可以使用 -json:data.json
选项直接将 JSON 作为输入提供给转换,并使用例如
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:function name="mf:group" as="map(*)*">
<xsl:param name="persons" as="map(*)*"/>
<xsl:for-each-group select="$persons" group-by="?PERSON_ID">
<xsl:sequence select="map { 'PersonId' : current-grouping-key(),'lastName' : ?LAST_NAME } } }"/>
</xsl:for-each-group>
</xsl:function>
<xsl:output method="json" indent="yes"/>
<xsl:template match=".">
<xsl:sequence select="array { mf:group(?*) }"/>
</xsl:template>
</xsl:stylesheet>
我认为我们会在下一任市长 Saxon Java 版本中看到类似的选择。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。