XSLT: Generating integer IDs and reference them having string keys on the input

Andrej Adamenko

I need to generate integer IDs for products and than reference related products by those integer IDs in the output. On the input I have string keys representing this relationship. Thank you for your help.

Input:

<root>
  <products>
    <product>
      <!-- a unique string key of this node between the other product nodes -->
      <stringKey>AppleRef</stringKey>
      <Name>Apple</Name>
      <relatedProducts>
        <!-- a reference to product/StringKey of Orange -->
        <relatedProductStringKey>OrangeRef</relatedProductStringKey>
        <!-- other related products may follow -->
      </relatedProducts>
    </product>
    <product>
      <stringKey>OrangeRef</stringKey>
      <Name>Orange</Name>
      <relatedProducts>
        <relatedProductStringKey>AppleRef</relatedProductStringKey>
      </relatedProducts>
    </product>
  </products>
</root>

Expected output:

<root>
  <products>
    <P>
      <ProductInfo>
        <!-- a unique integer ID of this node between the other ProductsInfo nodes -->
        <ProductID>0</ProductID>
        <ProductRef>AppleRef</ProductRef>
        <ProductName>Apple</ProductName>
      </ProductInfo>
      <R>
        <ProductRelatedInfo>

          <!-- a unique integer ID of this node between the other ProductRelatedInfo nodes -->
          <RelatedID>0</RelatedID>

          <!-- a reference to ProductInfo/ProductID of Orange -->
          <RelatedProductID>1</RelatedProductID>

        </ProductRelatedInfo>
        <!-- other related products may follow -->

      </R>
    </P>
    <P>
      <ProductInfo>
        <ProductID>1</ProductID>
        <ProductRef>OrangeRef</ProductRef>
        <ProductName>Orange</ProductName>
      </ProductInfo>
      <R>
        <ProductRelatedInfo>
          <RelatedID>1</RelatedID>
          <RelatedProductID>0</RelatedProductID>
        </ProductRelatedInfo>
      </R>
    </P>
  </products>
</root>
michael.hor257k

This is easy to do using a key. For example, the following stylesheet:

XSLT 1.0

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

<xsl:key name="product" match="product" use="stringKey" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="stringKey">
    <ProductID><xsl:value-of select="count(../preceding-sibling::product)"/></ProductID>
    <ProductRef><xsl:value-of select="."/></ProductRef>
</xsl:template>

<xsl:template match="relatedProductStringKey">
    <RelatedProductID><xsl:value-of select="count(key('product', .)/preceding-sibling::product)"/></RelatedProductID>
</xsl:template>

</xsl:stylesheet>

when applied to your input, will return:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <products>
      <product>
         <ProductID>0</ProductID>
         <ProductRef>AppleRef</ProductRef>
         <Name>Apple</Name>
         <relatedProducts>
            <RelatedProductID>1</RelatedProductID>
         </relatedProducts>
      </product>
      <product>
         <ProductID>1</ProductID>
         <ProductRef>OrangeRef</ProductRef>
         <Name>Orange</Name>
         <relatedProducts>
            <RelatedProductID>0</RelatedProductID>
         </relatedProducts>
      </product>
   </products>
</root>

If you prefer a meaningless, though not necessarily numeric ID, you might prefer the simpler:

XSLT 1.0

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

<xsl:key name="product" match="product" use="stringKey" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="stringKey">
    <ProductID><xsl:value-of select="generate-id(..)"/></ProductID>
    <ProductRef><xsl:value-of select="."/></ProductRef>
</xsl:template>

<xsl:template match="relatedProductStringKey">
    <RelatedProductID><xsl:value-of select="generate-id(key('product', .))"/></RelatedProductID>
</xsl:template>

</xsl:stylesheet>

The exact result depends on the processor, for example Saxon might return:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <products>
      <product>
         <ProductID>d0e3</ProductID>
         <ProductRef>AppleRef</ProductRef>
         <Name>Apple</Name>
         <relatedProducts>
            <RelatedProductID>d0e11</RelatedProductID>
         </relatedProducts>
      </product>
      <product>
         <ProductID>d0e11</ProductID>
         <ProductRef>OrangeRef</ProductRef>
         <Name>Orange</Name>
         <relatedProducts>
            <RelatedProductID>d0e3</RelatedProductID>
         </relatedProducts>
      </product>
   </products>
</root>

while libxslt will produce something like:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <products>
    <product>
      <ProductID>idp116928</ProductID>
      <ProductRef>AppleRef</ProductRef>
      <Name>Apple</Name>
      <relatedProducts>
        <RelatedProductID>idp1506944</RelatedProductID>
      </relatedProducts>
    </product>
    <product>
      <ProductID>idp1506944</ProductID>
      <ProductRef>OrangeRef</ProductRef>
      <Name>Orange</Name>
      <relatedProducts>
        <RelatedProductID>idp116928</RelatedProductID>
      </relatedProducts>
    </product>
  </products>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

XSLT 2.0 generating xml:ids on select elements

From Dev

XSLT 2.0 generating xml:ids on select elements

From Dev

Generating a subroutine reference from a string

From Dev

Reference values: string or integer?

From Dev

Should I use encryption or hashes for generating custom reference ids?

From Dev

Keyboard input and different keys having different response

From Dev

Having trouble with implementing a system that detects if an input is a integer or not

From Dev

Ruby Hash with integer keys changed to string keys

From Dev

Dynamically create IDs for jQuery Mobile elements, then reference them

From Dev

Integer input to a function that expects const reference

From Dev

Convert python string into integer without commas in them

From Dev

InputMismatchException for String input into integer field

From Dev

File input containing string and integer

From Dev

python string input to integer conversion

From Dev

InputMismatchException for String input into integer field

From Dev

String to Integer Input Verification Conversion

From Dev

invalid input syntax for integer (string)

From Dev

Change dictionary keys from string to integer

From Dev

python string format() with dict with integer keys

From Dev

Having a user input an integer, or quitting by pressing 'q' in python

From Dev

generating unique ids in hive

From Dev

Generating Random IDs for Database

From Dev

Generating a compile-time constant integer from a literal string

From Dev

Generating a compile-time constant integer from a literal string

From Dev

counting sort with input string having alphabets and numbers

From Dev

Integer variables pass by value, string variables by reference?

From Dev

URL helpers with string keys deprecated but params uses them as string by default

From Dev

URL helpers with string keys deprecated but params uses them as string by default

From Dev

Generating xpath with xslt

Related Related

  1. 1

    XSLT 2.0 generating xml:ids on select elements

  2. 2

    XSLT 2.0 generating xml:ids on select elements

  3. 3

    Generating a subroutine reference from a string

  4. 4

    Reference values: string or integer?

  5. 5

    Should I use encryption or hashes for generating custom reference ids?

  6. 6

    Keyboard input and different keys having different response

  7. 7

    Having trouble with implementing a system that detects if an input is a integer or not

  8. 8

    Ruby Hash with integer keys changed to string keys

  9. 9

    Dynamically create IDs for jQuery Mobile elements, then reference them

  10. 10

    Integer input to a function that expects const reference

  11. 11

    Convert python string into integer without commas in them

  12. 12

    InputMismatchException for String input into integer field

  13. 13

    File input containing string and integer

  14. 14

    python string input to integer conversion

  15. 15

    InputMismatchException for String input into integer field

  16. 16

    String to Integer Input Verification Conversion

  17. 17

    invalid input syntax for integer (string)

  18. 18

    Change dictionary keys from string to integer

  19. 19

    python string format() with dict with integer keys

  20. 20

    Having a user input an integer, or quitting by pressing 'q' in python

  21. 21

    generating unique ids in hive

  22. 22

    Generating Random IDs for Database

  23. 23

    Generating a compile-time constant integer from a literal string

  24. 24

    Generating a compile-time constant integer from a literal string

  25. 25

    counting sort with input string having alphabets and numbers

  26. 26

    Integer variables pass by value, string variables by reference?

  27. 27

    URL helpers with string keys deprecated but params uses them as string by default

  28. 28

    URL helpers with string keys deprecated but params uses them as string by default

  29. 29

    Generating xpath with xslt

HotTag

Archive