如何使用 XSLT 更改节点名称并将 XML 中该节点的数据复制到另一个节点



我的基本XML就像

<?xml version="1.0" encoding="iso-8859-1"?>
<Report version="1.0">
  <sourceName Identification="xyz"/>
  <sourcesys Identification="mycomp">
    <Manager>
      <ManagerNo>1023114455</ManagerNo>
      <Address>Delhi,India</Address>
      <Currency>
        <CurrencyType>Rupee</CurrencyType>
      </Currency>
    </Manager>
    <Manager>
      <ManagerNo>236784455</ManagerNo>
      <Address>California,USA</Address>
      <Currency>
        <CurrencyType>Dollar</CurrencyType>
      </Currency>
    </Manager>
  </sourcesys>
</Report>

我想将此 XML 转换为以下 XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ManagerDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ManagerDetail>
    <ManagerNo>1023114455</ManagerNo>
    <Address>
      <PermenantAdd>California,USA</PermenantAdd>
    </Address>
    <CurrencyID>Rupee</CurrencyID>
  </ManagerDetail>
  <ManagerDetail>
    <ManagerNo>236784455</ManagerNo>
    <Address>
      <PermenantAdd>Delhi,India</PermenantAdd>
    </Address>
    <CurrencyID>Dollar</CurrencyID>
  </ManagerDetail>
</managerDetails>

以下是标签的映射:

  • 源 = 经理详细信息
  • 经理 = 经理详细信息
  • 经理编号 = 经理编号
  • 地址 = 永久添加
  • 货币类型 = 货币 ID

您将如何使用 XSLT 执行此操作?

对于此类转换,您应该基于标识模板进行构建,该标识模板本身会复制 XSLT 中的所有节点

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

这意味着您只需要为要转换的节点编写模板(话虽如此,这完全由 ManagerNo 元素编写(。

例如,要转换(类似于管理器(,您可以这样做

<xsl:template match="sourcesys">
   <ManagerDetails>
      <xsl:apply-templates select="@*|node()"/>
   </ManagerDetails>
</xsl:template>

要删除元素,例如 sourceName,您将拥有一个忽略它的模板

<xsl:template match="sourceName"/>

要处理地址,这略有不同,因为您需要添加一个新元素。在这种情况下,我将编写一个与其文本节点匹配的模板,并在那里添加一个元素,如下所示:

<xsl:template match="Address/text()">
   <PermenantAdd>
      <xsl:value-of select="." />
   </PermenantAdd>
</xsl:template>

最后,对于 CurrencyTypeCurrencyID,这很简单,但您还需要一个模板来跳过父 Currency 元素,并处理其子元素,如下所示:

<xsl:template match="Currency ">
   <xsl:apply-templates select="@*|node()"/>
</xsl:template>

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="/*">
        <xsl:apply-templates select="@*|node()"/>
   </xsl:template>
   <xsl:template match="sourcesys">
      <ManagerDetails>
         <xsl:apply-templates select="@*|node()"/>
      </ManagerDetails>
   </xsl:template>
   <xsl:template match="Manager">
      <ManagerDetail>
         <xsl:apply-templates select="@*|node()"/>
      </ManagerDetail>
   </xsl:template>
   <xsl:template match="sourceName"/>
   <xsl:template match="Address/text()">
      <PermenantAdd>
         <xsl:value-of select="." />
      </PermenantAdd>
   </xsl:template>
   <xsl:template match="Currency">
      <xsl:apply-templates select="@*|node()"/>
   </xsl:template>
   <xsl:template match="CurrencyType">
      <CurrencyID>
         <xsl:apply-templates select="@*|node()"/>
      </CurrencyID>
   </xsl:template>
</xsl:stylesheet>

另请注意,有一个模板<xsl:template match="/*">可以跳过根元素,它是否有命名空间并不重要。

编辑:如果您不想跨源系统的属性复制,而是使用新属性,请尝试像这样替换模板

   <xsl:template match="sourcesys">
      <ManagerDetails href="...">
         <xsl:apply-templates select="node()"/>
      </ManagerDetails>
   </xsl:template>

请注意 xsl:apply-templates 现在缺少@*,因此它不会跨任何其他属性进行复制。

如果需要帮助,

试试这个:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" standalone="yes" encoding="utf-8" version="1.0"/>
  <xsl:template match="/">
    <xsl:element name="ManagerDetails">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>
  <xsl:template match="/Report/sourcesys/Manager">
    <xsl:element name="ManagerDetail">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>
  <xsl:template match="/Report/sourcesys/Manager/ManagerNo">
    <xsl:copy-of select="."/>
  </xsl:template>
  <xsl:template match="/Report/sourcesys/Manager/Address">
    <xsl:copy>
      <xsl:element name="PermenantAdd">
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="/Report/sourcesys/Manager/Currency/CurrencyType">
    <xsl:element name="CurrencyID">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="text()"></xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新