Need to show hierarchy of an unknown XML file
Added by Anonymous almost 20 years ago
Legacy ID: #2973514 Legacy Poster: Curtis (cdfisher07)
I need to output the hierarchy of an XML file without knowing ahead of time what hierarchy exists. It could have infinite levels, but for the sake of simplicity, let's say it only has 10. The reason I need this is because I am using a FLASH tree that takes it's input from a file that is formatted as below to produce the hierarchy and I want to produce that same formatting. &Item1=*Transaction &Item2=**Source &Item3=***SourceID &Item4=***Author &Item5=*Measurer &Item6=**Another Source ... As you can see, it's the asterisk that actually denotes the parent-child relationship and that is why I'm having difficulty. I have to determine if a node is a child of another node, and at what level the parent exists and so on. I'm not an expert at recursion, but I know how it is done with procedural languages, and XSLT makes it even more confusing. All the example code I have found has thus far assummed that the XML structure is flat and is of the "push" style that knows ahead of time what the node name, and structure will be. Here is an example of what I have to work with... XML ------------------------------------ <TransactionSet> <DocumentID>String</DocumentID> <SiteID>String</SiteID> <Author>String</Author> <Date Context="SDEDocument">1967-08-13</Date> <Transaction Type="Add" TypeContext="Original" Condition="Planned" Corrected="1" ProcessCode="String" ActionCode="String"> <Source Type="SDE"> <SourceID>String</SourceID> <SourceAuthor>String</SourceAuthor> <Measurer>String</Measurer> <MeasurementDate>1967-08-13</MeasurementDate> <ModeOfTransportation>String</ModeOfTransportation> <TotalGrossVolume UnitOfMeasure="gram">3.1415926535897932384626433832795</TotalGrossVolume> <TotalGrossWeight UnitOfMeasure="gram">3.1415926535897932384626433832795</TotalGrossWeight> <MTONumber>String</MTONumber> <TransferAuthority>String</TransferAuthority> <RefNumber Context="String">String</RefNumber> <RemarksTransactionSource>String</RemarksTransactionSource> </Source> <ActivityDate>1967-08-13</ActivityDate> <Site> <SiteID Context="Default">String</SiteID> </Site> <Nature>String</Nature> <User> <UserID>String</UserID> <Action>String</Action> <RemarksUser>String</RemarksUser> </User> </Transaction> </TransactionSet> Here is the XSL I'm using... <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="no"/> <xsl:template match="/"> <xsl:for-each select="//"> <xsl:variable name="parentnode" select="name()"/> <br/> <xsl:value-of select="$parentnode"/>-<xsl:value-of select="position()"/> <xsl:for-each select="@"> .a<xsl:value-of select="name()"/>-<xsl:value-of select="position()"/> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet> ...and here is the output: TransactionSet-1 DocumentID-2 SiteID-3 Author-4 Date-5 .aContext-1 Transaction-6 .aType-1 .aTypeContext-2 .aCondition-3 .aCorrected-4 .aProcessCode-5 .aActionCode-6 Source-7 .aType-1 SourceID-8 SourceAuthor-9 Measurer-10 MeasurementDate-11 ModeOfTransportation-12 TotalGrossVolume-13 .aUnitOfMeasure-1 TotalGrossWeight-14 .aUnitOfMeasure-1 MTONumber-15 I am trapping for the attributes and displaying them on the same line as the element tag with a .a appended to it. The position() is working well to give me the proper sequence number, and the inner iteration is producing the atributes correctly. However, determining the node-leaf relationship is beyond my current skills with XSLT. But yet, XSLT seems to be perfectly suited to solve this problem for me. I appreciate any help or advice with this problem, and rest assurred, I will keep slogging away until I solve it, or hopefully, someone else will offer a solution. Curtis
Replies (1)
RE: Need to show hierarchy of an unknown XML - Added by Anonymous almost 20 years ago
Legacy ID: #2973568 Legacy Poster: Michael Kay (mhkay)
XSLT coding questions, unless they are specifically related to Saxon, are best directed to the xsl-list at www.mulberrytech.com. You're much more likely to find someone there to give you a detailed answer. As far as I can see this problem requires a standard recursive descent, going from each element to its children, along the lines <xsl:template match=""> <xsl:value-of select="name()"/> <xsl:apply-templates/> </xsl:template> You might want to use count(ancestor::) to determine the depth of the element in the input tree, or <xsl:number level="any" count="*"> to determine the absolute sequence number of each element within the document. Michael Kay
Please register to reply