Home > Enterprise >  I need more help traversing an XML document
I need more help traversing an XML document

Time:11-04

I wrote some code recently to traverse XML using <xsl:for-each select="//dfor:children/dfor:child">

This code worked well, but I know need to traverse same child elements but from a specified parent as there are now multiple children sets - they have a parent name of "otom_businessPartner" and "otom_expense" as iterated results are for both child sets, not the single set I need.

Here is the XML:

<?xml version="1.0" encoding="UTF-8"?>
<dfor:form-data xmlns:dfor="http://kana.com/dforms">
    <dfor:field>
        <dfor:name>otom_businessPartner</dfor:name>
        <dfor:children>
            <dfor:child>
                <dfor:field>
                    <dfor:name>txt_bpName</dfor:name>
                    <dfor:value>Southampton City Council</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>txt_bpRelationship</dfor:name>
                    <dfor:value>Southampton City Council</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>txt_bpShare</dfor:name>
                    <dfor:value>Southampton City Council</dfor:value>
                </dfor:field>
            </dfor:child>
            <dfor:child>
                <dfor:field>
                    <dfor:name>txt_bpName</dfor:name>
                    <dfor:value>222222222</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>txt_bpRelationship</dfor:name>
                    <dfor:value>222222222</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>txt_bpShare</dfor:name>
                    <dfor:value>2222222222222222</dfor:value>
                </dfor:field>
            </dfor:child>
        </dfor:children>
    </dfor:field>

    <dfor:field>
        <dfor:name>otom_expenses</dfor:name>
        <dfor:children>
            <dfor:child>
                <dfor:field>
                    <dfor:name>sel_expense</dfor:name>
                    <dfor:value>Advertising</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>txt_other2</dfor:name>
                    <dfor:value/>
                </dfor:field>
                <dfor:field>
                    <dfor:name>num_actual</dfor:name>
                    <dfor:value>100</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>num_private</dfor:name>
                    <dfor:value>100</dfor:value>
                </dfor:field>
            </dfor:child>
            <dfor:child>
                <dfor:field>
                    <dfor:name>sel_expense</dfor:name>
                    <dfor:value>Leasing charges</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>txt_other2</dfor:name>
                    <dfor:value>car</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>num_actual</dfor:name>
                    <dfor:value>200</dfor:value>
                </dfor:field>
                <dfor:field>
                    <dfor:name>num_private</dfor:name>
                    <dfor:value>100</dfor:value>
                </dfor:field>
            </dfor:child>
        </dfor:children>
    </dfor:field>

</dfor:form-data>

And here is the XLST:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dfor="http://kana.com/dforms" exclude-result-prefixes="dfor">

    <xsl:param name="name" /> 
    <xsl:param name="ref" /> 
    
    <xsl:template match="/">
        <html>
            <body>
                
                        <p><strong>SECTION TITLE</strong></p>

                        <xsl:for-each select="//dfor:child">
                            
                            <h4>Business partner <xsl:value-of select="position()" />:</h4>
                            <ul>
                            <xsl:for-each select="dfor:field">

                                <!-- Business Partner's name -->
                                <xsl:if test="dfor:name='txt_bpName'">
                                    <li><strong>Business Partner's name: </strong> <xsl:value-of select="dfor:value"/></li>
                                </xsl:if>

                                <!-- Business Partner's relationship -->
                                <xsl:if test="dfor:name='txt_bpRelationship'">
                                    <li><strong>Business Partner's relationship: </strong> <xsl:value-of select="dfor:value"/></li>
                                </xsl:if>

                                <!-- Share of profits -->
                                <xsl:if test="dfor:name='txt_bpShare'">
                                    <li><strong>Share of profits: </strong> <xsl:value-of select="dfor:value"/></li>
                                </xsl:if>
                                
                            </xsl:for-each>
                            </ul>
        
                        </xsl:for-each>

            </body>
        </html> 
    </xsl:template>
</xsl:stylesheet>

It returns all 4 children (2 from otom_businessPartners, and 2 from otom_expense) I need to figure out the correct traversal back up "otom_businessPartners" and "otom_expense" to retirn just the two I want.

This is line of line that needs to be working. ' <xsl:for-each select="//dfor:child">'

It needs to be something like ' <xsl:for-each select="//children/dfor:child[name='otom_businessPartners']"> which obviously isnt correct, as I want to return just the children of "otom_businessPartners".

CodePudding user response:

Since you did not post the expected result, I am mostly guessing here. It seems you want to do something like (simplified example):

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:dfor="http://kana.com/dforms" 
exclude-result-prefixes="dfor">

<xsl:template match="/dfor:form-data">
    <html>
        <body>
            <xsl:for-each select="dfor:field[dfor:name='otom_businessPartner']/dfor:children/dfor:child">
                <h4>
                    <xsl:text>Business partner </xsl:text>
                    <xsl:value-of select="position()" />
                    <xsl:text>:</xsl:text>
                </h4>
                <ul>
                    <!-- Business Partner's name -->
                    <li>
                        <strong>Business Partner's name: </strong>
                        <xsl:value-of select="dfor:field[dfor:name='txt_bpName']/dfor:value"/>
                    </li>

                    <!-- more here -->
                    
                </ul>
            </xsl:for-each>

        </body>
    </html> 
</xsl:template>

</xsl:stylesheet>

Applied to your input example, this will return:

Result

<html>
   <body>
      <h4>Business partner 1:</h4>
      <ul>
         <li><strong>Business Partner's name: </strong>Southampton City Council
         </li>
      </ul>
      <h4>Business partner 2:</h4>
      <ul>
         <li><strong>Business Partner's name: </strong>222222222
         </li>
      </ul>
   </body>
</html>

Rendered:

enter image description here

  • Related