如何在组合旧节点和生成新UUID元素的同时转换XML

时间:2012-04-03 15:09:48

标签: xml xslt

我有以下XML文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dictionaryEntry type="CM_Vserver">
    <uuid>27bfb32f-baa1-4571-abb5-c644c132ceea</uuid>
    <object-attributes>
        <object-attribute type="String" naturalKey="false" name="admin_state">
            <description>some text</description>
        </object-attribute>
    </object-attributes>
    <object-references>
        <object-reference refCol="cluster_id" naturalKey="true" name="cluster">
            <type>49f5f09e-dcae-4922-98aa-0b4a58f27fda</type>
            <description>some text</description>
        </object-reference>
    </object-references>
</dictionaryEntry>

我希望将其转换为以下XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dictionaryEntry type="CM_Vserver">
    <uuid>27bfb32f-baa1-4571-abb5-c644c132ceea</uuid>
    <dictionary-entry-properties>
        <dictionary-entry-property xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="objectAttribute" attributeType="String" name="admin_state" naturalKey="false">
            <uuid>9ccbbd60-0e62-4ae7-b158-e6825441f987</uuid>
            <description>some text</description>
        </dictionary-entry-property>
        <dictionary-entry-property xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="objectReference" referredColumn="cluster_id" name="cluster" naturalKey="true">
            <uuid>afa8c22d-5af9-424e-af6d-106ad96dadbd</uuid>
            <referenceType>49f5f09e-dcae-4922-98aa-0b4a58f27fda</referenceType>
            <description>some text</description>
        </dictionary-entry-property>
    </dictionary-entry-properties>
</dictionaryEntry>

请注意,我需要进行以下更改:

  1. 将object-attribute重命名为dictionary-entry-property
  2. 将对象引用重命名为dictionary-entry-property
  3. 将object-references / object-reference / type重命名为referenceType
  4. 在名为dictionary-entry-properties
  5. 的单个节点中组合ex对象引用和ex对象引用
  6. 为每个对象引用生成UUID
  7. 提前致谢。

1 个答案:

答案 0 :(得分:0)

在我回答之前,有两件事需要协调:

首先:您尚未描述所需XML中出现的所有更改。例如,<dictionary-entry-property>元素似乎获得了以前缺​​少的命名空间;另外,一些属性名称会改变。既然你没有在你的变化列表中指定那些,我会忽略它们;让我知道他们最终会变得很重要,我会修改我的答案。

第二:出于某些特定原因,你需要一个UUID吗?或者这个价值只需要是唯一的吗?

如果您回答了前者,请参阅此链接以了解如何执行此操作:XSLT generate UUID。简而言之,您很可能不得不依赖外部方法,例如EXSLT库或random number generation with FXSL

另一方面,如果您回答后者,the generate-id()函数将帮助您(我在答案中使用此方法)。在任一情况下,请考虑以下事项:

对您提供的XML运行此XSLT时:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- Identity Template: copies everything as-is -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Add new <dictionary-entry-properties> element to -->
  <!-- contain all of our result elements -->
  <xsl:template match="dictionaryEntry">
    <xsl:copy>
      <dictionary-entry-properties>
        <xsl:apply-templates/>
      </dictionary-entry-properties>
    </xsl:copy>
  </xsl:template>

  <!-- Replace <object-attributes> nodes with -->
  <!-- <dictionary-entry-properties> nodes -->
  <xsl:template match="object-attributes">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- Replace <object-attribute> and <object-reference> elements -->
  <!-- with a new <dictionary-entry-property> element; additionally, -->
  <!-- create a <uuid> element with a unique value -->
  <xsl:template match="object-attribute | object-reference">
    <dictionary-entry-property>
      <xsl:apply-templates select="@*"/>
      <uuid>
        <xsl:value-of select="generate-id()"/>
      </uuid>
      <xsl:apply-templates/>
    </dictionary-entry-property>
  </xsl:template>

  <!-- Rename <type> elements (with <object-reference> parents -->
  <!-- and <object-references> grandparents) to <referenceType> -->
  <xsl:template match="object-references/object-reference/type">
    <referenceType>
      <xsl:apply-templates/>
    </referenceType>
  </xsl:template>

  <!-- <object-references> elements should be removed altogether -->
  <xsl:template match="object-references">
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

生成了这个XML:

<?xml version="1.0" encoding="UTF-8"?>
<dictionaryEntry>
  <dictionary-entry-properties>
    <uuid>27bfb32f-baa1-4571-abb5-c644c132ceea</uuid>
    <dictionary-entry-property type="String" naturalKey="false" name="admin_state">
      <uuid>i__21420544_12</uuid>
      <description>some text</description>
    </dictionary-entry-property>
    <dictionary-entry-property refCol="cluster_id" naturalKey="true" name="cluster">
      <uuid>i__21420544_25</uuid>
      <referenceType>49f5f09e-dcae-4922-98aa-0b4a58f27fda</referenceType>
      <description>some text</description>
    </dictionary-entry-property>
  </dictionary-entry-properties>
</dictionaryEntry>