0

I have the following XML file

<?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>

and I would like to transform it into the following 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>

Note that I need to do the following changes:

  1. Rename object-attribute into dictionary-entry-property
  2. Rename object-reference into dictionary-entry-property
  3. Rename object-references/object-reference/type into referenceType
  4. Combine ex object-references and ex object-references in single node called dictionary-entry-properties
  5. Generate UUID for each object-references

Thanks in advance.

Sasha Korman
  • 157
  • 1
  • 8

1 Answers1

0

Before I answer, two things to reconcile:

First: you haven't described all of the changes that appear in your desired XML. For example, the <dictionary-entry-property> element seems to gain a previously-missing namespace; additionally, some attribute names change. Since you don't specify those in your list of changes, I'm going to ignore them; let me know they do end up being important and I'll revise my answer.

Second: do you need a UUID for some specific reason? Or does that value simply need to be unique?

If you answered the former, see this link for a discussion on how this might be done: XSLT generate UUID. In a nutshell, you'll most likely have to rely on external methodologies, such as the EXSLT library or random number generation with FXSL.

If, on the other hand, you answered the latter, the generate-id() function will help you (I use this approach in my answer). In either scenario, consider the following:

When this XSLT is run against your provided XML:

<?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>

this XML is produced:

<?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>
Community
  • 1
  • 1
ABach
  • 3,743
  • 5
  • 25
  • 33