Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

renumbering xml elements with XSLT

Status
Not open for further replies.

csbdeady

Programmer
May 18, 2002
119
GB
After reading around Google search results, and experimenting a bit I'm stuck with trying to renumber elements in an XML source via XSLT.

If I have something like:

<something uid="1" />
<something uid="2" />
<something uid="3" />

What would be the most straight-forward XSLT code to allow me to pass in a parameter to allow me to insert an element between uid's 1 and 2, giving it's uid attribute the value of "2" (ie: the same value as the element it is inserted before) and renumbering the subsequent elements' uid attributes accordingly to give me:

<something uid="1" />
<something uid="2" /> - this is the newly inserted element
<something uid="3" /> - this was formally UID="2"
<something uid="4" /> - this was formally UID="3"

Note that uid="1" remains constant, it is only uid="2" and uid="3" that get renumbered to allow for the newly inserted element.

Thanks
 
Why do the elements have to be numbered? They inherently have numbering - their position in the nodeset.

Jon

"I don't regret this, but I both rue and lament it.
 
Ahah! Good point - but if I have to ID attributes - one denoting its "unique"ness and the other its order I could have:

<something uid="1" oid="1" />
<something uid="2" oid="2" />

to start with, but later want:
<something uid="2" oid="1" />
<something uid="1" oid="2" />

To facilitate re-ordering but preserving the uniqueness (uid) I need to be able to update the oid values (ok my original post asked to update the uid - that was a typo)

The problem I have still stands though - how to insert a new element taking the oid (not uid!) of an existing one, and how to renumber the subsequent oid's?
 
I don't get why you need theses attributes. XML is not like a database. Elements are by definition unique and the order is captured inherently by the order in the nodeset.

Jon

"I don't regret this, but I both rue and lament it.
 
I need these elements because I am generating a TestSuite of TestCases in an XML file format to be played back through Compuware's TestPartner automated test tool. Each <testcase/> must have both oid and uid attributes - the uid defines the unique identifier for the TestCase - which means that we can tell people "TC number 2 failed, TC number 3 passed" etc. However the order in which the Test Cases are executed also needs defining - and this uses the oid value.

Yes one could store the data in a database, however for our purposes this would be slow and cumbersome - the reason for this is that when running an automated test we need to install the auto-test software on the test machine (which is fair enough as one can't run the test cases without such), but if I also have to install a DBMS as well then that means the machine is no longer in an appropriate test state.

Therefore the best solution is to store the Test Cases in an XML file - no special DBMS required (as the Test Cases are processed within TestPartner).

One could talk for hours on this, but I'm deviating from the point - which is how to update the oid values when inserting a new Test Case.
 
I think the easiest way is to output the nodes with oid less than the oid param, then output a new node with the uid set to the highest available + 1 and oid set to the oid param, then output the nodes with oid not less than the oid param with oid set to oid + 1. If that makes sense.

This assumes that your nodes are ordered by oid (and gives a default value for the oid to insert a node before):
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:param name="oid" select="2"/>
  <xsl:template match="/">
    <root>
      <xsl:apply-templates select="root"/>
    </root>
  </xsl:template>
  <xsl:template match="root">
    <xsl:copy-of select="something[position() &lt; $oid]"/>
    <something uid="{something[not(../something/@uid &gt; @uid)]/@uid + 1}" oid="{$oid}"/>
    <xsl:apply-templates select="something[not(position() &lt; $oid)]"/>
  </xsl:template>
  <xsl:template match="something">
    <something uid="{@uid}" oid="{@oid + 1}"/>
  </xsl:template>
</xsl:stylesheet>

Jon

"I don't regret this, but I both rue and lament it.
 
By the way, I was working with this test XML:
Code:
<root>
  <something uid="2" oid="1"/>
  <something uid="1" oid="2"/>
  <something uid="3" oid="3"/>
</root>

Jon

"I don't regret this, but I both rue and lament it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top