首页 > 解决方案 > 从 XSLT 中的序列化 XML 中删除命名空间

问题描述

我正在尝试通过 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"
  }
 ]
}

小提琴:https ://xsltfiddle.liberty-development.net/6q1SDkM/5

我面临摘要节点在输出中显示命名空间的问题。看起来命名空间来自员工节点中提到的 XML 树。我如何删除命名空间。同样在日期格式中,我们可以得到最多 7 位的小数秒。现在我只能得到几毫秒

标签: jsonxmlxsltazure-logic-appsxslt-3.0

解决方案


正如我在对上一个问题的评论中所说,您可以通过明确不复制名称空间的模式推送元素:

<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>

https://xsltfiddle.liberty-development.net/6q1SDkM/6


推荐阅读