如何将xml元素和子元素属性值转换为一个新元素和子元素

时间:2013-05-31 19:15:37

标签: xml xslt transform

我一直在寻找一个好的文档来解释这个没有成功。 这是我的问题:

这是我的要求

  • 根元素必须更改名称(已完成),
  • 第二级元素中只应有一个属性名称应该在元素中转换元素。
  • 应删除第二级元素及其余属性
  • 第三级元素(第二级元素内)中的所有属性都转换为第二级元素。
  • 应删除第三级元素。

当前

<list>

<type name="drum" acustic="true" pieces="5" >
    <part name="pearl" id="0" version="0" displayOrder="0" customizationLevel="basic" />
    <part name="dw" id="1" version="0" displayOrder="0" customizationLevel="basic" />
</type>

<type name="guitar" acustic="true" pieces="1" >
    <part name="fender" id="0" version="0" displayOrder="0" customizationLevel="basic" />       
</type>

期望的

<instrumentList>
    <instrument>
    <instrumentType>drum</instrumentType>
    <instrumentID>0</instrumentID>
    <instrumentBrand>pearl</instrumentBrand>
    <version>0</version>
    <displayOrder>0</displayOrder>
    <customizationLevel>basic</customizationLevel>
    </instrument>

    <intrument>
    <instrumentType>drum</instrumentType>
    <instrumentID>1</instrumentID>
    <instrumentBrand>dw</instrumentBrand>
    <version>0</version>
    <displayOrder>0</displayOrder>
    <customizationLevel>basic</customizationLevel>
    </instrument>
    <instrument>    
    <instrumentType>guitar</instrumentType>
    <instrumentID>0</instrumentID>
    <instrumentBrand>fender</instrumentBrand>
    <version>0</version>
    <displayOrder>0</displayOrder>
    <customizationLevel>basic</customizationLevel>
    </instrument>
</instrumentList>

所以我按照以下教程和线程没有成功 Thread 1 Thread 2

我可以做部分但不是全部。 我确信这里有一些我不理解的东西,特别是删除元素和创建新元素并使用一些属性,而不是所有属性。 即使有人可以指出我有一个很好的参考,我可以理解xslt如何解析xml所以我可以有一个更好的主意,因为我发现他们转换每个属性或元素的所有例子,不幸的是不是我的情况。

非常感谢任何帮助

1 个答案:

答案 0 :(得分:1)

好吧,你可以从一个将属性转换为元素的通用模板开始,如下所示:

<xsl:template match="@*">
   <xsl:element name="{local-name()}">
      <xsl:value-of select="."/>
   </xsl:element>
</xsl:template>

但是根据您的要求,某些属性需要重命名为元素,因此您可以为这些元素编写特定的模板。例如, @id 元素看起来像是要重命名为 InstrumentId

<xsl:template match="@id">
   <instrumentID>
      <xsl:value-of select="."/>
   </instrumentID>
</xsl:template>

需要额外工作的唯一一点是,与 part 元素匹配的模板是您需要输出 instrumentType 元素,其值等于父元素属性。除此之外,您只需要选择要转换的所有属性元素

<xsl:template match="part">
   <instrumentType>
      <xsl:value-of select="../@name"/>
   </instrumentType>
   <xsl:apply-templates select="@*"/>
</xsl:template>

对于第二级类型元素,您可以让XSLT的内置模板处理它。

试试这个XSLT

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

   <xsl:template match="list">
      <instrument>
         <xsl:apply-templates/>
      </instrument>
   </xsl:template>

   <xsl:template match="part">
      <instrumentType>
         <xsl:value-of select="../@name"/>
      </instrumentType>
      <xsl:apply-templates select="@*"/>
   </xsl:template>

   <xsl:template match="@id">
      <instrumentID>
         <xsl:value-of select="."/>
      </instrumentID>
   </xsl:template>

   <xsl:template match="@name">
      <instrumentBrand>
         <xsl:value-of select="."/>
      </instrumentBrand>
   </xsl:template>

   <xsl:template match="@*">
      <xsl:element name="{local-name()}">
         <xsl:value-of select="."/>
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

当应用于您的XML时(假设关闭列表标记),输出以下内容

<instrument>
   <instrumentType>drum</instrumentType>
   <instrumentBrand>pearl</instrumentBrand>
   <instrumentID>0</instrumentID>
   <version>0</version>
   <displayOrder>0</displayOrder>
   <customizationLevel>basic</customizationLevel>

   <instrumentType>drum</instrumentType>
   <instrumentBrand>dw</instrumentBrand>
   <instrumentID>1</instrumentID>
   <version>0</version>
   <displayOrder>0</displayOrder>
   <customizationLevel>basic</customizationLevel>

   <instrumentType>guitar</instrumentType>
   <instrumentBrand>fender</instrumentBrand>
   <instrumentID>0</instrumentID>
   <version>0</version>
   <displayOrder>0</displayOrder>
   <customizationLevel>basic</customizationLevel>
</instrument>