logo
down
shadow

Flat to Hierarchical XSLT Transform


Flat to Hierarchical XSLT Transform

By : user2950372
Date : November 17 2020, 11:55 AM
I hope this helps you . I'm having pretty significant trouble figuring out how to convert a flat XML into a hierarchical result using an XSLT V1 transform. I would post my XSLT, but I'm not sure I'm even approaching it correctly. I know I need to create and use Keys, but, regardless of attempting to apply every example I've found here and elsewhere (many, many, many...), it simply doesn't work. , I suggest you try it this way:
XSLT 1.0 + EXSLT set:distinct()
code :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tns="http://services.xxx.com/ClientService"
xmlns:set="http://exslt.org/sets"
extension-element-prefixes="set">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="client" match="tns:client" use="tns:ClientID" />
<xsl:key name="plan" match="tns:plan" use="concat(tns:ClientID, '|', tns:episodeID)" />

<xsl:template match="/">
    <env:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <env:Header/>
        <env:Body>
            <tns:getClientRS>
                <xsl:copy-of select="tns:Acknowledgement"/>
                <tns:clients>
                    <!-- client -->
                    <xsl:for-each select="set:distinct(env:Envelope/env:Body/tns:getClientRS/tns:client/tns:ClientID)">
                        <xsl:variable name="clientID" select="." />
                        <xsl:copy-of select="."/>
                         <tns:episodes>
                            <!-- episode -->
                            <xsl:for-each select="set:distinct(key('client', .)/tns:episodeID)">
                                <tns:Episode>
                                    <xsl:variable name="episodeID" select="." />
                                    <xsl:copy-of select="."/>
                                        <!-- plans -->
                                        <tns:Guarantors>
                                            <xsl:for-each select="key('plan', concat($clientID, '|', $episodeID))">
                                                <tns:Guarantor>
                                                    <xsl:copy-of select="tns:guarantorID"/>
                                                    <tns:Plan>
                                                        <xsl:copy-of select="tns:guarantorPlan"/>
                                                    </tns:Plan>
                                                </tns:Guarantor>
                                            </xsl:for-each> 
                                        </tns:Guarantors>
                                </tns:Episode>
                            </xsl:for-each> 
                        </tns:episodes> 
                    </xsl:for-each> 
                </tns:clients>
            </tns:getClientRS>
        </env:Body>
    </env:Envelope>
</xsl:template>

</xsl:stylesheet>


Share : facebook icon twitter icon
XSLT flat to hierarchical

XSLT flat to hierarchical


By : Dave
Date : March 29 2020, 07:55 AM
will be helpful for those in need What you are proposing is correct but could be generalized and simplified as:
code :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://ait.com/cr/" version="1.0">

    <xsl:output indent="yes"/>

    <xsl:key name="sons" match="CRStructure" use="cr_parent"/>
    <xsl:param name="maxLevels">3</xsl:param>

    <xsl:template match="NewDataSet">
        <CR>
            <CRItems>
                <xsl:apply-templates select="key('sons', 0)"/>
            </CRItems>
        </CR>
    </xsl:template>

    <xsl:template match="CRStructure">
        <xsl:param name="level">1</xsl:param>
        <xsl:if test="$level &lt;= $maxLevels">
            <CRItem ObjectId="{objid}">
                <CrId>
                    <xsl:value-of select="cr_id"/>
                </CrId>
                <CRItems>
                    <xsl:apply-templates select="key('sons', cr_id)">
                        <xsl:with-param name="level" select="$level  + 1"/>
                    </xsl:apply-templates>
                </CRItems>
            </CRItem>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
xslt for flat to hierarchical xml

xslt for flat to hierarchical xml


By : Marco Pagani
Date : March 29 2020, 07:55 AM
wish of those help I am trying to create a transformation that will map a flat structure ( with parent/child ids) into a hierarchical structure. I have included a simple example below. The actual data has over 4000 elements. I do not have data on the max depth, bu the transformation should be able to be recursive to n level. to this post xslt-flat-to-hierarchical I tried to follow its pattern to my situation. Unfortunately, it is not recursing! Any help would be really appreciated! ! , I think the problem is with your initial apply templates
code :
 <xsl:apply-templates select="key('sons', 0)"/>
<xsl:apply-templates select="key('sons', '000000')"/>
<xsl:key name="sons" match="item" use="number(PARENT)"/>
<xsl:apply-templates select="key('sons', number(ID))">
Transform flat XML to hierarchical XML

Transform flat XML to hierarchical XML


By : Antonio
Date : March 29 2020, 07:55 AM
To fix this issue Your key definitions are fine, the problem is in your second level of for-each:
code :
<xsl:for-each select="../row[generate-id() = generate-id(key('kl2', concat(e1,'#',l2))[1])]">
<xsl:for-each select="key('ke1', e1)[generate-id() = generate-id(key('kl2', concat(e1,'#',l2))[1])]">
Transform hierarchical data into flat table

Transform hierarchical data into flat table


By : 4our
Date : March 29 2020, 07:55 AM
Hope this helps I am researching about hierarchical data (as a solution to generalize work orders) by using ms sql. , What about this trick?
code :
DECLARE @tbl TABLE(ID INT,ParentID INT,Type VARCHAR(10),Value VARCHAR(10))
INSERT INTO @tbl VALUES
 (1,0,'Num','327')
,(2,1,'Sector','21')
,(3,1,'Sector','22')
,(4,2,'Product','ARF')
,(5,2,'Product','BRF')
,(6,3,'Product','NS')
,(7,3,'Product','MS')
,(8,4,'Quantity','20')
,(9,5,'Quantity','30')
,(10,6,'Quantity','25')
,(11,7,'Quantity','60');

WITH recCTE AS
(
    SELECT *,0 AS HLevel,Type + N'="' + CAST(Value AS NVARCHAR(MAX)) + N'" ' AS attr
    FROM @tbl WHERE ParentID=0

    UNION ALL

    SELECT t.*,r.HLevel+1,attr+t.Type + N'="' + CAST(t.Value AS NVARCHAR(MAX)) + N'" '
    FROM @tbl AS t
    INNER JOIN recCTE AS r ON t.ParentID=r.ID
)
SELECT CAST(N'<row ' + attr  + N'/>' AS XML)
FROM recCTE
WHERE HLevel=3
FOR XML PATH(''),ROOT('root')
<root>
  <row Num="327" Sector="22" Product="MS" Quantity="60" />
  <row Num="327" Sector="22" Product="NS" Quantity="25" />
  <row Num="327" Sector="21" Product="BRF" Quantity="30" />
  <row Num="327" Sector="21" Product="ARF" Quantity="20" />
</root>
DECLARE @tbl TABLE(ID INT,ParentID INT,Type VARCHAR(100),Value VARCHAR(100))
INSERT INTO @tbl VALUES
 (1,0,'Num','327')
,(2,1,'Sector','21')
,(3,1,'Sector','22')
,(4,2,'Product','ARF')
,(5,2,'Product','BRF')
,(6,3,'Product','NS')
,(7,3,'Product','MS')
,(8,4,'Quantity','20')
,(9,5,'Quantity','30')
,(10,6,'Quantity','25')
,(11,7,'Quantity','60')
,(13,11,'SomeMore','Test as fourth');

WITH recCTE AS
(
    SELECT t.*
          ,0 AS HLevel
          ,t.Type + N'="' + CAST(t.Value AS NVARCHAR(MAX)) + N'" ' AS attr
          ,CASE WHEN EXISTS(SELECT 1 FROM @tbl AS x WHERE x.ParentID=t.ID) THEN 0 ELSE 1 END AS IsLeaf
    FROM @tbl AS t WHERE ParentID=0

    UNION ALL

    SELECT t.*
          ,r.HLevel+1
          ,attr+t.Type + N'="' + CAST(t.Value AS NVARCHAR(MAX)) + N'" '
          ,CASE WHEN EXISTS(SELECT 1 FROM @tbl AS x WHERE x.ParentID=t.ID) THEN 0 ELSE 1 END AS IsLeaf
    FROM @tbl AS t
    INNER JOIN recCTE AS r ON t.ParentID=r.ID
)
SELECT CAST(N'<row ' + attr  + N'/>' AS XML)
FROM recCTE
WHERE IsLeaf=1
FOR XML PATH(''),ROOT('root')
<root>
  <row Num="327" Sector="22" Product="MS" Quantity="60" SomeMore="Test as fourth" />
  <row Num="327" Sector="22" Product="NS" Quantity="25" />
  <row Num="327" Sector="21" Product="BRF" Quantity="30" />
  <row Num="327" Sector="21" Product="ARF" Quantity="20" />
</root>
DECLARE @tbl TABLE(ID INT,ParentID INT,Type VARCHAR(100),Value VARCHAR(100))
INSERT INTO @tbl VALUES
 (38,0,'Num','327')
,(39,38,'Sector','21')
,(40,38,'Sector','22')
,(43,40,'Product','NS')
,(44,40,'Product','MS')
,(50,40,'Temp','RAS')
,(48,44,'Quantity','60')
,(47,43,'Quantity','25')
,(41,39,'Product','ARF')
,(42,39,'Product','BRF')
,(49,39,'Temp','RAS')
,(51,39,'Cible','Acarien A.')
,(46,42,'Quantity','30')
,(52,42,'Cible','Acarien B.')
,(45,41,'Quantity','20');

WITH recCTE AS
(
    SELECT t.*
          ,0 AS HLevel
          ,t.Type + N'="' + CAST(t.Value AS NVARCHAR(MAX)) + N'" ' AS attr
          ,CASE WHEN EXISTS(SELECT 1 FROM @tbl AS x WHERE x.ParentID=t.ID) THEN 0 ELSE 1 END AS IsLeaf
    FROM @tbl AS t WHERE ParentID=0

    UNION ALL

    SELECT t.*
          ,r.HLevel+1
          ,attr+t.Type + N'="' + CAST(t.Value AS NVARCHAR(MAX)) + N'" '
          ,CASE WHEN EXISTS(SELECT 1 FROM @tbl AS x WHERE x.ParentID=t.ID) THEN 0 ELSE 1 END AS IsLeaf
    FROM @tbl AS t
    INNER JOIN recCTE AS r ON t.ParentID=r.ID
)
SELECT CAST(N'<row ' + attr  + N'/>' AS XML)
FROM recCTE
WHERE IsLeaf=1
FOR XML PATH(''),ROOT('root')
<root>
  <row Num="327" Sector="22" Temp="RAS" />
  <row Num="327" Sector="22" Product="MS" Quantity="60" />
  <row Num="327" Sector="22" Product="NS" Quantity="25" />
  <row Num="327" Sector="21" Temp="RAS" />
  <row Num="327" Sector="21" Cible="Acarien A." />
  <row Num="327" Sector="21" Product="BRF" Quantity="30" />
  <row Num="327" Sector="21" Product="BRF" Cible="Acarien B." />
  <row Num="327" Sector="21" Product="ARF" Quantity="20" />
</root>
Hierarchical numbering of flat XML with XSLT?

Hierarchical numbering of flat XML with XSLT?


By : Marc
Date : March 29 2020, 07:55 AM
Any of those help I don't think you can achieve this with level="multiple".
I think you can get the required number for (say) an h3 element using
code :
<xsl:template match="h3" mode="number">
  <xsl:number level="any" count="h1"/>
  <xsl:text>.</xsl:text>
  <xsl:number level="any" count="h2" from="h1"/>
  <xsl:text>.</xsl:text>
  <xsl:number level="any" count="h3" from="h2"/>
</xsl:template>
Related Posts Related Posts :
  • How can I debug a corrupt docx file?
  • Validating XML with standard XSD schema in Visual Studio 2017
  • flex: display number of children in datagrid column
  • Default namespace in XML file doesn't work with XSD, why?
  • Spring 3.1 : Cannot find the declaration of element 'beans'
  • Merging similar attributes with XSLT
  • WSO2 ESB: XML response in WSO2 REST API call not parsed
  • Add image id to image path based on condition
  • How to test data of an XML file
  • how can i solve "No grammar constraints (DTD or XML Schema) referenced in the document." WARNING
  • Why does XML not display in browser but correctly does in XML Notepad 2007 (Microsoft)?
  • How to output based on the input conditions
  • XML to Fixed width text file formatted details
  • Use parameter value as in select in xslt
  • Counting the number of times an xslt transform is done
  • Trouble using an environment variable's value in VBS
  • HTTP response containing XML book-ended by unexpected characters
  • Trying to retrieve just one node value in xslt
  • Select name of alias of xmlns atribute by xpath
  • Get and set text in a xml field
  • Need help to create an XSLT
  • Counting frequency of tags / attributes in XML using XSLT
  • Update nodes via merge without changing node order?
  • XSL Selecting A Nested Field (From Shopify XML Output)
  • How do I add a semi colon between text fragments but not at the end of text fragments?
  • Parse XSL Date Format
  • Network protocol structure definitions in machine readable form (xml,json,other?)?
  • invalid byte '?' at position 2 of 2-byte sequence validation/parse error
  • Inserting a node into XML
  • Replace before and after string in vim
  • XML/XSL Table won't populate
  • shadow
    Privacy Policy - Terms - Contact Us © ourworld-yourmove.org