How do I dynamically edit an XML file?

Viewed 47

I have an XML file that looks like this:

<Student_x0020_Query>
    <HUSID>1234567891234</HUSID>
    <OWNSTU>00012345</OWNSTU>
    <BIRTHDTE>2000-12-27T00:00:00</BIRTHDTE>
    <FNAMES>John</FNAMES>
    <SURNAME>Smith</SURNAME>
    <ID>21</ID>
    <Instance_NUMHUS>00012345</Instance_NUMHUS>
    <COMDATE>2021-10-01T00:00:00</COMDATE>
    <ENDDATE>2022-09-30T00:00:00</ENDDATE>
    <SPLENGTH>3</SPLENGTH>
    <UNITLGTH>1</UNITLGTH>
    <EntryProfile_NUMHUS>00012345</EntryProfile_NUMHUS>
    <DOMICILE>England</DOMICILE>
    <POSTCODE>AA1 1AA</POSTCODE>
    <StudentEquality_NUMHUS>00060735</StudentEquality_NUMHUS>
    <DISABLE>00</DISABLE>
    <ETHNIC>01</ETHNIC>
    <GENDERID>01</GENDERID>
    <NATION>GB</NATION>
    <RELBLF>01</RELBLF>
    <SEXID>01</SEXID>
    <SEXORT>04</SEXORT>
</Student_x0020_Query>

This is simply one of many of the 'Student' element in the XML file--there are thousands of them.

I need to do one of a few things to this data.

  1. Firstly, I need to separate out some of the data within the 'Student' element, and make it into its own element as a child of 'Student'. So, for example, the line that reads, '<Instance_NUMHUS>00012345</Instance_NUMHUS>'--I want to make that, and the 4 lines below it, a child element of 'Student'.
  2. Secondly, I need to be able to remove certain attributes/lines from elements.
  3. Thirdly, I need to be able to do both of the above en masse. I need to apply one of the two things above to every 'Student' element, for example. So when I make '<Instance_NUMHUS>00012345</Instance_NUMHUS>' and the 4 lines below it its own element, I need the same thing to happen to every element.

If you can help me, I am really begging you to help me.

Thank you.

1 Answers

This is a routine task for XSLT. It's easily done in XSLT; however, the learning curve is not trivial because it's a powerful language, and may be rather unlike other languages you have used in the past.

Here are some pointers:

If an element X has children A, B, C, and D, and you want to move C and D down a level, you can write

<xsl:template match="X">
  <xsl:copy-of select="A, B"/>
  <new-level>
     <xsl:copy-of select="C, D"/>
  </new-level>
</xsl:template>

When you say "attributes", I don't see any XML attributes in your document, so I assume you mean child elements. If you want to drop an element ZZZ, simply do nothing when you encounter it:

<xsl:template match="ZZZ"/>

Template rules in a stylesheet are applied to every element that they match, provided that the element is selected for processing in an <xsl:apply-templates/> instruction. For this kind of processing it's usual to define a default that copies all elements unchanged:

<xsl:mode on-no-match="shallow-copy"/>

and then you only need to define explicit rules for elements where you want to make some change.

I've used features from the latest version of XSLT, 3.0, here. It's not difficult however to do a simple transformation like this using XSLT 1.0 if that's all you have available.

Related