Avatar billede hitze Nybegynder
13. september 2003 - 09:25 Der er 16 kommentarer

Gruppering af nodes - XML loop-i-loop-i-loop

Jeg har følgende XML kode som skal bearbejdes i asp:

  <?xml version="1.0" encoding="ISO-8859-1" ?>
  <person id="180138" language="Danish" agegroup="30-40">
  Johnny Larsen
  <adress>adresse</adress>
  <zip>3000</zip>
  <occupation>
  Marketing
  <attrib id="2073">attrib 1</attrib>
  <attrib id="4246">attrib 2</attrib>
  <attrib id="4247">attrib 3</attrib>
  <attrib id="2076">attrib 4</attrib>
  </occupation>
  <leisure>
  Tennis
  <attrib id="1075">attrib 1</attrib>
  <attrib id="4248">attrib 2</attrib>
  <attrib id="2072">attrib 3</attrib>
  <attrib id="4245">attrib 4</attrib>
  </leisure>
  </person>
  <person id="180138" language="Danish" agegroup="50-60">
  Svend Madsen
  <adress>adresse</adress>
  <zip>3000</zip>
  <occupation>
  Admin
  <attrib id="2073">attrib 1</attrib>
  <attrib id="4246">attrib 2</attrib>
  <attrib id="4247">attrib 3</attrib>
  <attrib id="2076">attrib 4</attrib>
  </occupation>
  <leisure>
  Golf
  <attrib id="1075">attrib 1</attrib>
  <attrib id="4248">attrib 2</attrib>
  <attrib id="2072">attrib 3</attrib>
  <attrib id="4245">attrib 4</attrib>
  </leisure>
  </person>
  <person id="180139" language="Danish" agegroup="40-50">
  Kim Holm
  <adress>adresse</adress>
  <zip>4000</zip>
  <occupation>
  Education
  <attrib id="4247">attrib 1</attrib>
  <attrib id="2076">attrib 2</attrib>
  </occupation>
  <leisure>
  Nature
  <attrib id="1075">attrib1</attrib>
  <attrib id="4245">attrib2</attrib>
  </leisure>
  </person>
  <person id="180140" language="German" agegroup="40-50">
  Jan Schmidt
  <adress>adresse</adress>
  <zip>8000</zip>
  <occupation>
  Unoccupied
  <attrib id="2073">attrib 1</attrib>
  <attrib id="4246">attrib 2</attrib>
  <attrib id="4247">attrib 3</attrib>
  <attrib id="2076">attrib 4</attrib>
  </occupation>
  <leisure>
  Sports
  <attrib id="1075">attrib 1</attrib>
  <attrib id="4248">attrib 2</attrib>
  <attrib id="2072">attrib 3</attrib>
  <attrib id="4245">attrib 4</attrib>
  </leisure>
  </person>

Det skulle være indlysende at værdierne for de forskellige attrib er meget variabel. 

Det jeg gerne skal er at få output grupperet på 1) childnoden language i person-noden, og derefter 2) på noden zip.

Derudover skal der for hver enkelt person loopes på alle attrib-noder - en node som jeg ikke kender antallet af forekomster af. Der kan være 0 eller uendeligt.

Det ønskede output skulle gerne være noget i stil med:

(loop på language startes for at gruppere disse)
Language: Danish

(loop på alle personer på noden zip, så den grupperer alle med identisk postnummer)
Postnummer (zip): 3000

Johnny Larsen
Adresse: adresse
Marketing    Tennis
(loop på attrib for hhv. occupation og leisure i kolonner)
attrib1        attrib1
attrib2        attrib2
attrib3        attrib3
attrib4     attrib4

Svend Madsen
Adresse: adresse
Admin        Golf
(loop på attrib for hhv. occupation og leisure i kolonner)
attrib1        attrib1
attrib2        attrib2
attrib3        attrib3
attrib4     attrib4

(ved forekomst af nyt postnummer, startes næste loop)
Postnummer (zip): 4000

Kim Holm
Adresse: adresse
Education    Nature
(loop på attrib for hhv. occupation og leisure i kolonner)
attrib1        attrib1
attrib2        attrib2

(nu er der ikke flere forekomster af language Danish, så næste loop på lanuguage startes)
Language: German

(loop på zip)
Postnummer (zip): 8000

Jan Schmidt
Adresse: adresse
Zip: 8000
Unoccupied    Sports
(loop på attrib for hhv. occupation og leisure i kolonner)
attrib1        attrib1
attrib2        attrib2
attrib3        attrib3
attrib4     attrib4

Kort sagt er "hierarkiet" for de loops der skal laves som følger
Loop på language
  herunder loop på postnummer
      herunder loop på attrib

Hvis mere info ønskes, så spørg løs! Skulle dog være rimelig til at gå til for dem der har prøvet det før, hvilket jeg altså ikke har ;-)
Avatar billede thor.ostergaard Nybegynder
13. september 2003 - 09:28 #1
vil du lave det i xslt eller DOM?
Avatar billede hitze Nybegynder
13. september 2003 - 13:24 #2
Yderst relevant info ;-)

Skal være i DOM.
Avatar billede thor.ostergaard Nybegynder
13. september 2003 - 16:06 #3
Kigger på det...
Det bliver nok en kombination af xsl og asp da jeg skal holde xsl kursus i næste uge.

For en ordens skyld bør du lige sørge for at din XML er gyldig - den du har lagt op bryder med reglen om, at der kun må være ét rod element.
Avatar billede hitze Nybegynder
13. september 2003 - 22:46 #4
Lyder godt - du må meget gerne fokusere mest på asp, selvom du - naturligvis - hælder til xsl.

Mht. gyldigheden, så har jeg udeladt rodelementer i gengivelsen af koden herinde, af hensyn til overskueligheden. Bare så du ved at der er flere, men de er ikke relevante for det aktuelle spørgsmål
Avatar billede thor.ostergaard Nybegynder
15. september 2003 - 09:02 #5
Skal du have det ud i HTML format?
Avatar billede hitze Nybegynder
15. september 2003 - 09:07 #6
Jo tak - det skal ud i html via response.write's i asp.
Avatar billede Slettet bruger
15. september 2003 - 09:10 #7
XSLT's templates struktur er jo ellers skræddersyet til sådanne ting...

/CS
Avatar billede hitze Nybegynder
15. september 2003 - 09:22 #8
Ja, men udi XSL er jeg (so far) meget lidt bevandret, så medmindre der kan komme et helt svar med brugbar xsl-tmpl klar til implementering quick and dirty, er asp at foretrække.
Avatar billede thor.ostergaard Nybegynder
15. september 2003 - 09:28 #9
Det kommer - er næsten færdig :-)
Avatar billede thor.ostergaard Nybegynder
15. september 2003 - 09:36 #10
Her har du et xsl - der i store træk gør som du forventer:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <xsl:for-each select="/personer/person[not(@language=preceding::person/@language)]">
            <xsl:variable name="lang" select="@language"/>
                <p>Language:<xsl:value-of select="@language"></xsl:value-of></p>
                <xsl:for-each select="/personer/person[@language=$lang]/zip[not(.=preceding::zip)]">
                    <xsl:variable name="zip" select="." />
                    <p>Zip: <xsl:value-of select="."></xsl:value-of></p>
                    <xsl:for-each select="/personer/person[@language=$lang]/zip[.=$zip]">
                        <p><xsl:value-of select="parent::person/text()"></xsl:value-of></p>
                    <p>Adresse: <xsl:value-of select="preceding-sibling::adress"></xsl:value-of></p>
                    <p><b><xsl:value-of select="following-sibling::occupation/text()"></xsl:value-of></b></p>
                    <xsl:for-each select="following-sibling::occupation/attrib">
                        <p><xsl:value-of select="."></xsl:value-of></p>
                    </xsl:for-each>
                    <p><b><xsl:value-of select="following-sibling::leisure/text()"></xsl:value-of></b></p>
                    <xsl:for-each select="following-sibling::leisure/attrib">
                        <p><xsl:value-of select="."></xsl:value-of></p>
                    </xsl:for-each> -->
                    </xsl:for-each>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
Avatar billede thor.ostergaard Nybegynder
15. september 2003 - 09:37 #11
Og asp koden der kalder stylesheetet kunne se sådan her ud (har bare nappet den et sted på nettet:
    <%
    Option Explicit

    Const XSL_PATH = "transform.xsl"

    dim sPath : sPath = Request.Querystring( "src" )

    dim oXml : Set oXml = Server.CreateObject( "Msxml2.DomDocument.4.0"
)
    oXml.Load Server.MapPath( sPath )

    dim oXsl : Set oXsl = Server.CreateObject( "Msxml2.DomDocument.4.0"
)
    oXsl.Load Server.MapPath( XSL_PATH )

    response.write oXml.TransformNode( oXsl )

    Set oXsl = Nothing
    Set oXml = Nothing
    %>
Avatar billede thor.ostergaard Nybegynder
15. september 2003 - 09:40 #12
Det var en sjov udfordring, som jeg kun har taget op for at træne min xsl - det har taget en del tid. Jeg har ikke tid til at gøre meget mere ved det i denne omgang.

God fornøjelse :-)
Avatar billede Slettet bruger
15. september 2003 - 10:51 #13
Bare for at "putte mine penge hvor min mund er" så er her min version af et XSLT stylesheet der genererer det ønskede output - jeg vil ikke have point; jeg lægger det udelukkende for at vise forskellen i tænkemåde - dette udnytter bare mere fordelen ved templates, og er efter min mening nemmere at redigere outputtet fra.

------
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />

    <xsl:template match="/">
        <h1>Output</h1>
        <xsl:apply-templates select="personer" />
    </xsl:template>

    <xsl:template match="personer">
        <xsl:for-each select="person/@language">
            <xsl:if test="not(preceding::person[@language = current()])">
                <xsl:apply-templates select="." />
            </xsl:if>
            <xsl:for-each select="ancestor::person[@language = current()]">
                <xsl:sort select="zip" />
                <xsl:if test="not(preceding-sibling::person[zip = current()/zip])">
                    <xsl:apply-templates select="zip" />
                </xsl:if>
                <xsl:apply-templates select="." />
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="person">
        <h4><xsl:apply-templates select="text()[1]" /></h4>
        Adresse: <xsl:apply-templates select="adress" />
        <table>
            <tr>
                <th><xsl:value-of select="occupation/text()[1]" /></th>
                <th><xsl:value-of select="leisure/text()[1]" /></th>
            </tr>
            <tr>
                <td>
                    <xsl:apply-templates select="occupation/attrib" />
                </td>
                <td>
                    <xsl:apply-templates select="leisure/attrib" />
                </td>
            </tr>
        </table>
    </xsl:template>

    <xsl:template match="@language">
        <h2>Language: <xsl:value-of select="." /></h2>
    </xsl:template>

    <xsl:template match="zip">
        <h3>Postnummer (zip): <xsl:value-of select="." /></h3>
    </xsl:template>

    <xsl:template match="attrib">
        <xsl:value-of select="." /><br />
    </xsl:template>

</xsl:stylesheet>
------
/CS
Avatar billede thor.ostergaard Nybegynder
15. september 2003 - 11:04 #14
respekt!
Avatar billede Slettet bruger
15. september 2003 - 11:24 #15
Taksaduha Thor - og selv tak for ærligheden på http://www.eksperten.dk/spm/400505/

/CS
Avatar billede thor.ostergaard Nybegynder
15. september 2003 - 11:33 #16
no problem - det er jo en meget sjov leg med disse point, men grundlæggende er det ikke derfor jeg er her.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester