从 XSLT 中的序列化 XML 中删除名称空间
Remove namespace from serialized XML in XSLT
我正在尝试通过 XSLT 3 中的一些转换将 XML 转换为 Json。我有示例 XML,如下所示
样本XML:
<Root>
<Employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Employee>
<name>abc</name>
</Employee>
<Employee>
<name>def</name>
</Employee>
<summary>
<Age>15</Age>
<tag1>dd</tag1>
<tag2>dd</tag2>
<tag2>dd</tag2>
</summary>
</Employees>
</Root>
我的 XSLT 模板
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output method="json" indent="yes"/>
<xsl:template match="/Root">
<xsl:for-each select="Employees">
<xsl:sequence select="map { 'Root' :
array {
Employee[name!=''] ! map {
'Name':data(name),
'Date': format-dateTime(current-dateTime(), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f0000001]Z'),
'Summary': 'Employee: ' || data(name) ||' Summary : ' || serialize(../summary)
}
}
}"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出:
{
"Root": [
{
"Summary":"Employee: abc Summary : <summary xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"><Age>15<\/Age><tag1>dd<\/tag1><tag2>dd<\/tag2><tag2>dd<\/tag2><\/summary>",
"Name":"abc",
"Date":"2021-02-08T09:03:22.4740000Z"
},
{
"Summary":"Employee: def Summary : <summary xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"><Age>15<\/Age><tag1>dd<\/tag1><tag2>dd<\/tag2><tag2>dd<\/tag2><\/summary>",
"Name":"def",
"Date":"2021-02-08T09:03:22.4740000Z"
}
]
}
Fiddle:https://xsltfiddle.liberty-development.net/6q1SDkM/5
我遇到摘要节点在输出中显示命名空间的问题。看起来命名空间来自 XML 树,在 Employee node.How 中提到,我可以删除命名空间。
同样在日期格式中,我们可以获得最多 7 位数的小数秒。现在我只能得到毫秒
正如我在对您上一个问题的评论中所说,您可以通过明确不复制名称空间的模式推送元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output method="json" indent="yes"/>
<xsl:template match="/Root">
<xsl:for-each select="Employees">
<xsl:sequence select="map { 'Root' :
array {
Employee[name!=''] ! map {
'Name':data(name),
'Date': format-dateTime(current-dateTime(), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f0000001]Z'),
'Summary': 'Employee: ' || data(name) ||' Summary : ' || ../summary => mf:strip-namespaces() => serialize()
}
}
}"/>
</xsl:for-each>
</xsl:template>
<xsl:mode name="strip-namespaces" on-no-match="shallow-copy"/>
<xsl:template mode="strip-namespaces" match="*">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:function name="mf:strip-namespaces" as="node()">
<xsl:param name="node" as="node()"/>
<xsl:apply-templates select="$node" mode="strip-namespaces"/>
</xsl:function>
</xsl:stylesheet>
我正在尝试通过 XSLT 3 中的一些转换将 XML 转换为 Json。我有示例 XML,如下所示
样本XML:
<Root>
<Employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Employee>
<name>abc</name>
</Employee>
<Employee>
<name>def</name>
</Employee>
<summary>
<Age>15</Age>
<tag1>dd</tag1>
<tag2>dd</tag2>
<tag2>dd</tag2>
</summary>
</Employees>
</Root>
我的 XSLT 模板
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output method="json" indent="yes"/>
<xsl:template match="/Root">
<xsl:for-each select="Employees">
<xsl:sequence select="map { 'Root' :
array {
Employee[name!=''] ! map {
'Name':data(name),
'Date': format-dateTime(current-dateTime(), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f0000001]Z'),
'Summary': 'Employee: ' || data(name) ||' Summary : ' || serialize(../summary)
}
}
}"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出:
{
"Root": [
{
"Summary":"Employee: abc Summary : <summary xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"><Age>15<\/Age><tag1>dd<\/tag1><tag2>dd<\/tag2><tag2>dd<\/tag2><\/summary>",
"Name":"abc",
"Date":"2021-02-08T09:03:22.4740000Z"
},
{
"Summary":"Employee: def Summary : <summary xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"><Age>15<\/Age><tag1>dd<\/tag1><tag2>dd<\/tag2><tag2>dd<\/tag2><\/summary>",
"Name":"def",
"Date":"2021-02-08T09:03:22.4740000Z"
}
]
}
Fiddle:https://xsltfiddle.liberty-development.net/6q1SDkM/5
我遇到摘要节点在输出中显示命名空间的问题。看起来命名空间来自 XML 树,在 Employee node.How 中提到,我可以删除命名空间。 同样在日期格式中,我们可以获得最多 7 位数的小数秒。现在我只能得到毫秒
正如我在对您上一个问题的评论中所说,您可以通过明确不复制名称空间的模式推送元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output method="json" indent="yes"/>
<xsl:template match="/Root">
<xsl:for-each select="Employees">
<xsl:sequence select="map { 'Root' :
array {
Employee[name!=''] ! map {
'Name':data(name),
'Date': format-dateTime(current-dateTime(), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f0000001]Z'),
'Summary': 'Employee: ' || data(name) ||' Summary : ' || ../summary => mf:strip-namespaces() => serialize()
}
}
}"/>
</xsl:for-each>
</xsl:template>
<xsl:mode name="strip-namespaces" on-no-match="shallow-copy"/>
<xsl:template mode="strip-namespaces" match="*">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:function name="mf:strip-namespaces" as="node()">
<xsl:param name="node" as="node()"/>
<xsl:apply-templates select="$node" mode="strip-namespaces"/>
</xsl:function>
</xsl:stylesheet>