0

我的基本 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>

下面是标签的映射:

  • sourcesys = managerDetail
  • 经理 = 经理详情
  • 经理编号 = 经理编号
  • 地址 = 永久地址
  • 货币类型 = 货币 ID

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

4

2 回答 2

1

尝试这个:

<?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>
于 2013-09-27T18:47:39.387 回答
1

对于这样的转换,您应该建立在身份模板之上,该模板本身会复制 XSLT 中的所有节点

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

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

例如,要转换sourcesys(类似于Manager),您可以这样做

<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="/*">可以跳过根元素,它是否具有命名空间并不重要。

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

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

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

如果你想

于 2013-09-27T18:54:22.167 回答