我的基本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>
最后,对于 CurrencyType 到 CurrencyID,这很简单,但您还需要一个模板来跳过父 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>