TurboLag06
TurboLag06

Reputation: 1

Nodes with Comma Separated List. Get Distinct Values and Create New Nodes

I need to create an xml output that groups all the wd:External_Value_Data/wd:Text fields with each distinct Internal Value.

                               <wd:root>
                                <wd:Integration_Map_Value_Data>
                                    <wd:Internal_Value_Data>
                                        <wd:Text>A1</wd:Text>
                                    </wd:Internal_Value_Data>
                                    <wd:External_Value_Data>
                                        <wd:Text>3402948659753553924</wd:Text>
                                    </wd:External_Value_Data>
                                </wd:Integration_Map_Value_Data>
                                <wd:Integration_Map_Value_Data>
                                    <wd:Internal_Value_Data>
                                        <wd:Text>A1,A2</wd:Text>
                                    </wd:Internal_Value_Data>
                                    <wd:External_Value_Data>
                                        <wd:Text>3402949092169519108</wd:Text>
                                    </wd:External_Value_Data>
                                </wd:Integration_Map_Value_Data>
                                <wd:Integration_Map_Value_Data>
                                    <wd:Internal_Value_Data>
                                        <wd:Text>A1,A2</wd:Text>
                                    </wd:Internal_Value_Data>
                                    <wd:External_Value_Data>
                                        <wd:Text>3402949293873597442</wd:Text>
                                    </wd:External_Value_Data>
                                </wd:Integration_Map_Value_Data>
                                <wd:Integration_Map_Value_Data>
                                    <wd:Internal_Value_Data>
                                        <wd:Text>A1,A2,A3</wd:Text>
                                    </wd:Internal_Value_Data>
                                    <wd:External_Value_Data>
                                        <wd:Text>3402949293873597654977</wd:Text>
                                    </wd:External_Value_Data>
                                </wd:Integration_Map_Value_Data>
                                </wd:root>

I've tried some forms of tokenize with no success. I'm open to solutions in xslt 2.0 or 3.0.

<root>
    <record>
       <type>A1</type>
        <document>3402948659753553924</document>
        <document>3402949092169519108</document>
        <document>3402949293873597442</document>
        <document>3402949293873597654977</document>
    </record>
    <record>
        <type>A2</type>
        <document>3402949092169519108</document>
        <document>3402949293873597442</document>
        <document>3402949293873597654977</document>
    </record>
    <record>
        <type>A3</type>
        <document>3402949293873597654977</document>
    </record>
</root>

Upvotes: 0

Views: 17

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

Grouping on the tokenized value seems the right approach, the next time consider to show an approach and how it failed, here is an XSLT 3.0 stylesheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xpath-default-namespace="http://example.com"
  exclude-result-prefixes="#all"
  expand-text="yes">
  
  <xsl:template match="root">
    <root>
      <xsl:for-each-group select="Integration_Map_Value_Data" group-by="tokenize(Internal_Value_Data/Text, ',')">
        <record>
          <type>{current-grouping-key()}</type>
          <xsl:apply-templates select="current-group()/External_Value_Data/Text"/>
        </record>
      </xsl:for-each-group>
    </root>
  </xsl:template>
  
  <xsl:template match="Text">
    <document>{.}</document>
  </xsl:template>
  
  <xsl:output indent="yes"/>

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

This needs the namespace of the wd elements in the place of xpath-default-namespace="http://example.com".

Upvotes: 0

Related Questions