Avatar billede amoelle Nybegynder
01. marts 2002 - 12:35 Der er 6 kommentarer og
1 løsning

3 svære om scope og tællere: XML-XSL

Her er tre rigtig svære !

Jeg har en lille xml og en tilhørende xsl (se nedenfor) samt det output, der leveres, når jeg med et lille javaprogram trækker XML'en igennem XSL'en.
Bruger IE5.5 (MSXML3)


Imidlertid vil jeg gerne have udvidet outputtet med nogle tællere, samt nogle attributter, der ligger udenfor scope-

1. problem TÆLLEREN af Item1|item2 + sum i sidste linie
*OUTPUT*  *ØNSKET OUTPUT**********
2      2  1  Jeg kan hardkode tallet 1
S      2 S 2    jeg kan sætte en counter
                på "type1|type2" og lægge 1 til
S       2 S 3  ditto   
2       2  4  jeg kan ikke bruge counteren mere,
                så hvordan får jeg lagt 1 til dvs 3
3      3  1  Jeg kan hardkode tallet 1
T       3 T 2  jeg kan sætte en counter
                på "type1|type2" og lægge 1 til
B       3 B 3  ditto
G       3 G 4  ditto
V       3 V 5  ditto
3       3  6  jeg kan ikke bruge counteren mere,
                så hvordan får jeg lagt 1 til, dvs 6
*SLUT*      11
      **SLUT**


2. problem Attributten medtages i et indre scope ?
*OUTPUT*  *ØNSKET OUTPUT**********
2      2  1  I-Id(=2) læses
S      2 S 2    I-ID kan ikke læses, da jeg nu er
                inde på næste niveau,
                nemlig type1|type2
S       2 S 3  ditto   
2       2  4  ditto
3      3  1  I-Id(=3) læses
T       3 T 2  I-ID kan ikke læses, da jeg nu er
                inde på næste niveau,
                nemlig type1|type2
B       3 B 3  ditto
G       3 G 4  ditto
V       3 V 5  ditto
3       3  6  ditto   
*SLUT*      11
      **SLUT**

3. problem en ny slut linie med et sumantal
*OUTPUT*  *ØNSKET OUTPUT**********
2      2  1 
S      2 S 2     
S       2 S 3 
2       2  4 
3      3  1 
T       3 T 2 
B       3 B 3 
G       3 G 4 
V       3 V 5 
3       3  6 
      11      tallet er lig med
                  3*antItem + antType1 + antType2 + 1
                  (=2*2+1+5+1 =11)

Men jeg kan jo ikke holde variablene antType1 og antType2 fra inderste scope, når jeg er tilbage i yderste scope ?












******************************** START PÅ XML *********
  <?xml version="1.0" encoding="iso-8859-1" ?>
  <?xxx1 kørsel="21/02-2002 16:48:13"?>
    <udtraek>
        <afregning>
        <Nr>111</Nr>
            <item>
                <I-Id>2</I-Id>
                <type-2>
                    <E-Id>S</E-Id>
                </type-2>
                <type-1>
                    <E-Id>S</E-Id>
                </type-1>
            </item>
            <item>
                <I-Id>3</I-Id>
                <type-2>
                    <E-Id>T</E-Id>
                </type-2>
                <type-2>
                    <E-Id>B</E-Id>
                </type-2>
                <type-2>
                    <E-Id>G</E-Id>
                </type-2>
                <type-2>
                    <E-Id>V</E-Id>
                </type-2>
            </item>
        </afregning>
    </udtraek>

******************************** SLUT PÅ xML *********

*******OUTPUT*************
2
S
S
2
3
T
B
G
V
3
***SLUT på OUTPUT*********

***ØNSKET OUTPUT**********
2  #1
2#S#2
2#S#3
2  #4
3  #1
3#T#2
3#B#3
3#G#4
3#V#5
3  #6
#11
***SLUT på ØNSKET OUTPUT**

******************************** START PÅ xsL *********
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
  <xsl:template match="/">
    <html>
      <head></head>
      <body>
        <xsl:apply-templates select="//item" />
      </body>
    </html>
  </xsl:template>

<xsl:template match="item">
  <TR>
    <br></br>
    <TD>
      <xsl:value-of select="I-Id"/>
      <xsl:apply-templates select="type-1"/>
      <xsl:apply-templates select="type-2"/>
    </TD>
    <TD>
      <br></br>
      <xsl:value-of select="I-Id"/>
    </TD>
  </TR>
</xsl:template>       
 
<xsl:template match="type-1|type-2">
  <br></br>
  <TR>
    <TD>
      <xsl:value-of select="E-Id"/>
    </TD>
  </TR>
</xsl:template>       
</xsl:stylesheet>
******************************** SLUT PÅ XML *********



Avatar billede Slettet bruger
01. marts 2002 - 21:48 #1
Hej - jeg gad godt kunne hjælpe, men er ærligt talt på herrens mark, da jeg ikke aner hvad det er du prøver på... jeg kan ikke engang se logikken i det ønskede output... hvad er det f.eks. for data du gemmer i XML filen?

/CS
Avatar billede amoelle Nybegynder
02. marts 2002 - 10:15 #2
Ja, OK, jeg kan godt se, at formatteringen ser lidt spøjs ud.
XML-Data er fra et konto udtræk, og de skal skrives i en fil, hvor der skal tilføjes nogle tællere, som ikke findes i xml'en.
Jeg håber nedenstående er mere klart.

Ad 1. problem
Den viste xml og xsl giver følgende output:

2
S
S
2
3
T
B
G
V
3

men jeg ønsker:
2 1
S 2
S 3
2 4
3 1
T 2
B 3
G 4
V 5
3 6

Dvs at jeg vil gerne tælle de linier, der indeholder attributten fra et type1 eller type2 element, men samtidig vil jeg gerne starte tælleren udfor item linien OG tælle videre ved slutningen af item'et. således at et item med 2 stk type1|type2 giver en sluttæller=4, og det næste item med 4 stk type1|type2 giver en sluttæller=6.



ad 2. problem
Jeg vil gerne kunne skrive attributten I-id ud, når jeg processerer type1|type2 elementer:
dvs istedet for output

2
S
S
2
3
T
B
G
V
3


vil jeg gerne have:

2
2 S
2 S
2
3
3 T
3 B
3 G
3 V
3

Problemet er at fange attributten I-id inde i type1|type2-scopet (når man bruger en template, - jeg har også forsøgt med med <xsl:for-each>, - men så mister man kontrollen over processeringen)

************************************
ad 3. problem

Jeg vil gerne kunne tælle alle outputlinierne:
så istedet for
2
S
S
2
3
T
B
G
V
3
vil jeg gerne have

2
S
S
2
3
T
B
G
V
3
11

hvor tallet 11 = 2*antalItem+(antalType1+antalType2)+1
              = 2*2+(2+4)+1 =11
(der var en slåfejl i den opr. udregning - beklager.

Men hvordan laver jeg en global variabel, der kan holde det tal ?
Der er jo ingen assignment operator, og position() kan jeg kun få til at virke, når jeg står med et element.
*********************
Kombinerer man så de tre løsninger, skulle man kunne få et output:

2  1
2 S 2
2 S 3
2  4
3  1
3 T 2
3 B 3
3 G 4
3 V 5
3  6
11

(klafferne var bare for at skille output'tegnene)

PS. - jeg kunne også bare få server-enden til at tilføje nye attributter i xml'en - og så bare lave ren præsentation.... ;-(
Avatar billede janegil Nybegynder
02. marts 2002 - 14:25 #3
Problemet ditt er å kunne se hva som finnes utenfor det elementet templaten din er i gang med?

I så fall tror jeg det kan la seg gjøre. Noe med akser og foregående søsken og sånt.

http://www.w3.org/TR/xpath#axes

<xsl:value-of select="preceding-sibling::I-id[position()=1]"/> eller noe.

Noe av det samme kan sikkert brukes for å finne position() til et last() element, selv om du står et annet sted i øyeblikket.

(Fø. er ikke I-id noe attributt, det er et element. Sånt flisespikkeri kan ofte være viktig, når andre ting er vanskelig å forstå samtidig)
Avatar billede Slettet bruger
02. marts 2002 - 15:26 #4
Okey dokey - så er jeg igang :-)

Her får du lige løsningen på den med 11-tallet - eftersom du bruger tabel-tags (tr/td) har jeg proppet en <table> udenom, så jeg bedre kan se hvad der sker - så er <br> -tags'ene også overflødige:

<xsl:template match="/">
    <html>
      <head></head>
      <body>
        <table width="100" border="1">
            <xsl:apply-templates select="//item" />
        </table>
        <p>
            Total: <b><xsl:value-of select="2 * count(//item) + (count(//type-1) + count(//type-2)) + 1" /></b>.
        </p>
      </body>
    </html>
  </xsl:template>

- Jeg vender tilbage med resten senere...
/CS
Avatar billede Slettet bruger
02. marts 2002 - 16:06 #5
Så er der kage :-)

Check det her ud, og lad mig høre om ikke det er det du skal bruge. Outputtet er i tabelform, og tælleren er lavet vha. en <script> blok inde i stylesheet'et - derfor de ekstra namespace definitioner.

Skriv evt. hvis du vil have en uddybende forklaring på det med script'ene...

/CS

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:counter="#bogus-namespace"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
version="1.0">
<xsl:output method="html" />
  <xsl:template match="/">
    <html>
      <head></head>
      <body>
        <table border="1">
            <tr>
                <th>I-Id</th><th>type-1/2</th><th>counter</th>
            </tr>
            <xsl:apply-templates select="//item" />
        </table>
        <p>
            Total: <b><xsl:value-of select="2 * count(//item) + (count(//type-1) + count(//type-2)) + 1" /></b>.
        </p>
      </body>
    </html>
  </xsl:template>

<xsl:template match="item">
  <tr>
    <td><xsl:value-of select="I-Id"/></td>
    <td>&#160;</td>
    <td><xsl:value-of select="counter:reset()" /></td>
  </tr>
  <xsl:apply-templates select="type-1"/>
  <xsl:apply-templates select="type-2"/>
  <tr>
      <td><xsl:value-of select="I-Id" /></td>
      <td>&#160;</td>
      <td><xsl:value-of select="counter:inc()"/></td>
  </tr>
</xsl:template>       
 
<xsl:template match="type-1|type-2">
    <tr>
        <td><xsl:value-of select="../I-Id" /></td>
        <td><xsl:value-of select="E-Id"/></td>
        <td><xsl:value-of select="counter:inc()" /></td>
    </tr>
</xsl:template>       

<msxsl:script language="javascript" implements-prefix="counter"><![CDATA[
var iCount = 1;
function inc() {
    return iCount++;
}

function reset() {
    iCount = 1;
    return iCount++;
}]]>
</msxsl:script>
</xsl:stylesheet>
Avatar billede amoelle Nybegynder
05. marts 2002 - 10:44 #6
Hej greystate !
Det virker rigtig godt, når man kører det igennem XSL-debugger, - så du får alle points'ene og hele min respekt ;-)
Jeg havde ikke tænkt på at sætte JavaScript ind.

Er det rigtigt at "#bogus-namespace" bare en slags dummy ?

-- og jeg skal lige finde ud af, hvad man bruger istedet for xmlns:msxsl="urn:schemas-microsoft-com:xslt", når det istedet skal være Java.

Jeg bruger nemlig javax.transform pakken (transformationen sker på serversiden), og den brokker sig over msxml og JavaScript, - men det opretter jeg i et andet spørgsmål.
/AM
Avatar billede Slettet bruger
05. marts 2002 - 11:53 #7
Yeps - det er en dummy - msxsl:script elementet overtager åbenbart referencer til prefix'et defineret i "implements-prefix" attributten.

Du skrev du brugte MSXML3 og IE5.5 - derfor tænkte jeg det var "safe" at bruge script...

Jeg mener at have svaret på noget lignende mht. Java her på eksperten før...

Tak for respekt og point :-)
/CS
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