使用xsl:copy-of更改节点的名称

时间:2016-01-27 15:02:14

标签: xml xslt

我正在使用XSLT对XML文档进行非规范化。

问题是节点的名称在不同级别使用,这导致结果文件中出现重复。

e.g。

XML源文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Customers>
    <Customer>
        <ID>1</ID>
        <Name>John Madsen</Name>
        <Accounts>
            <Account>
                <ID>111</ID>
                <Name>AAA</Name>
                <Value>11234</Value>                
            </Account>
            <Account>
                <ID>222</ID>
                <Name>BBB</Name>
                <Value>64</Value>
            </Account>
        </Accounts>        
    </Customer>

    <Customer>
        <ID>2</ID>
        <Name>Dona M. Graduate</Name>
        <Accounts>
            <Account>
                <ID>333</ID>
                <Name>CCC</Name>
                <Value>5215</Value>                
            </Account>
            <Account>
                <ID>555</ID>
                <Name>FFF</Name>
                <Value>6325</Value>
            </Account>
        </Accounts>        
    </Customer>
</Customers>

我想将其转换为一个简单的帐户列表,重复有关客户的信息,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Accounts>
    <Account>
        <CustomerID>1</CustomerID>
        <CustomerName>John Madsen</CustomerName>
        <ID>111</ID>
        <Name>AAA</Name>
        <Value>11234</Value>                
    </Account>
    <Account>
        <CustomerID>1</CustomerID>
        <CustomerName>John Madsen</CustomerName>
        <ID>222</ID>
        <Name>BBB</Name>
        <Value>64</Value>
    </Account>
    <Account>
        <CustomerID>2</CustomerID>
        <CustomerName>Dona M. Graduate</CustomerName>
        <ID>333</ID>
        <Name>CCC</Name>
        <Value>5215</Value>                
    </Account>
    <Account>
        <CustomerID>2</CustomerID>
        <CustomerName>Dona M. Graduate</CustomerName>
        <ID>555</ID>
        <Name>FFF</Name>
        <Value>6325</Value>
    </Account>
</Accounts>

我使用以下XLS代码:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <Accounts>
        <xsl:for-each select="Customers/Customer/Accounts/Account">
            <Account>
                <xsl:copy-of select="ancestor::Customer/*[not(*)] "/>
                <xsl:copy-of select="*" />
            </Account>                                
        </xsl:for-each>
    </Accounts>
</xsl:template>

</xsl:stylesheet> 

我收到了这个结果,请注意帐户如何有两个ID节点和名称节点,一个是帐户ID和名称,另一个是客户ID和名称。

<?xml version="1.0" encoding="UTF-8"?>
<Accounts>
   <Account>
      <ID>1</ID>
      <Name>John Madsen</Name>
      <ID>111</ID>
      <Name>AAA</Name>
      <Value>11234</Value>
   </Account>
   <Account>
      <ID>1</ID>
      <Name>John Madsen</Name>
      <ID>222</ID>
      <Name>BBB</Name>
      <Value>64</Value>
   </Account>
   <Account>
      <ID>2</ID>
      <Name>Dona M. Graduate</Name>
      <ID>333</ID>
      <Name>CCC</Name>
      <Value>5215</Value>
   </Account>
   <Account>
      <ID>2</ID>
      <Name>Dona M. Graduate</Name>
      <ID>555</ID>
      <Name>FFF</Name>
      <Value>6325</Value>
   </Account>
</Accounts>

如何在Customer节点中为复制的ID和Name添加前缀?

此致 拉菲

1 个答案:

答案 0 :(得分:1)

副本指令会复制所选节点集,您无法对其进行修改,因此我建议使用 apply-templates ,并在单独的模板中执行操作。以下代码将为您完成这项工作:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <Accounts>
        <xsl:for-each select="Customers/Customer/Accounts/Account">
            <Account>
                <xsl:apply-templates select="ancestor::Customer/*[not(*)]"/>
                <xsl:copy-of select="*" />
            </Account>                                
        </xsl:for-each>
    </Accounts>
</xsl:template>

<xsl:template match="Customer/*[not(*)]">
    <xsl:element name="{concat('Customer', name())}">
        <xsl:copy-of select="@*|node()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>