webForumDet fria alternativet

XSLT padding

63 svar · 3 813 visningar · startad av newberg · sida 3 av 4

newbergMedlem sedan nov. 201040 inlägg
#41

Eller False, lite beroende på hur jag formatterar sökvägen.
Eventuellt där jag gör fel...

newbergMedlem sedan nov. 201040 inlägg
#42

provade följande och då skrevs det iaf ut något, men dock så skriver den samma värde på de olika strängarna gång på gång, vilket den inte ska.
Dessutom så verkar inte delimitern agera heller.

<xsl:variable name="string1" select="(vägen/till/string1)" />
<xsl:variable name="string2" select="(vägen/till/string2)" />
<xsl:for-each select="$string1">
<xsl:for-each select="$string2">
xsl:value-of select="concat($string1, '&#13 ;', $string2)"/>
</xsl:for-each>
</xsl:for-each>
SPiNMedlem sedan mars 20007 896 inlägg
#43

Angående delimitern, skippa mellanrummet mellan 13 och ; (eller byt ut till entiteten som verkar vara kytum att använda).

Ska du verkligen nästla loopen så? Hur ser din XML-struktur ut?

newbergMedlem sedan nov. 201040 inlägg
#44

XML-strukturen:

<vägen>
	<till>
		<string1>
		<string2>
	<till>
<vägen>

Har som sagt försökt kors och tvärs med olika lösningar, det här är det närmsta jag kommit, då jag åtminstone får något utskrivet.

Anledningen att jag hade mellanslaget på min newline entitet var för att det skulle ses i texten.

newbergMedlem sedan nov. 201040 inlägg
#45

Anledningen till att jag behöver använda "for-each" är på grund av att String1 och String2 kan förekomma fler gånger i samma hierarki men med olika värden. Och jag vill alltså skriva ut alla förekomster av string1 och string2. Föresöket med koden några inlägg ovan funkade som sagt inte, då den bara skriver ut sammma värde om och om igen.

På nedanstående sätt förekommer String1 och 2 flera ggr, men med olika värden:

<vägen>
	<till>
		<string1> 1
		<string2> A
	</till>
        <till>
		<string1> 2
		<string2> B
	</till>
        <till>
		<string1> 3
		<string2> c
	<till>
<vägen>
SPiNMedlem sedan mars 20007 896 inlägg
#46
<xsl:for-each select="vägen/till">
    <xsl:value-of select="concat(string1, '&#xa;', string2)" />
</xsl:for-each>
newbergMedlem sedan nov. 201040 inlägg
#47

Får bara falsefalsefalsefalse utskrivet.

Tror kanske att jag inte beskrivit xml:en korrekt. Det här är en bättre beskrivning:

<vägen>
	<till>
		<string1> 1
		<string2> A
	</till>
        <till>
		<string1> 2
		<string2> B
	</till>
        <till>
		<string1> 1
		<string2> C
	</till>
<till>
		<string1> 2
		<string2> D
	</till>
<vägen>

Alltså, Som ni ser så kan string1 ha antingen värde 1 el 2.
Dessa är indikatorerna på vilken sträng som innehåller vad.

När string1=1 så skriver jag ut string2 och när string1=2 så skriver jag ut string 2.

Så det jag försökt göra nu är att skriva följande, utan lycka för övrigt:

<xsl:for-each select="Vägen/till/string2">
<xsl:value-of select="concat(String1=1,'&#xa;',String1=2)"/>
</xsl:for-each>
newbergMedlem sedan nov. 201040 inlägg
#48

Denna var knepig, inte ens Spin kommer med några förslag ;)

Jäkligt frustrerande, har suttit med det här problemet i flera dagar nu utan att få det att lira, spelar ingen roll hur jag vänder och vrider på koden x(

SPiNMedlem sedan mars 20007 896 inlägg
#49

Jag vet ju inte riktigt vad du vill göra, vill du verkligen konkatenera strängar?

Här är två förslag som fungerar mot samma XML-fil. Den första varianten använder sig av choose/when för att veta vad en nod innehåller, den andra konkatenerar strängar med en radbrytning.
file.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="file.xsl"?>
<root>
	<element>
		<node_a>NODE-A</node_a>
		<node_b>NODE-B</node_b>
	</element>
	<element>
		<node_a>NODE-A 2</node_a>
		<node_b>NODE-B 2</node_b>
	</element>
	<element>
		<node_a>NODE-A 3</node_a>
		<node_b>NODE-B 3</node_b>
	</element>
</root>

choose.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<html>
			<body>
				<pre>
					<xsl:for-each select="root/element">
						<xsl:choose>
							<xsl:when test="node_a='NODE-A'">
								<xsl:value-of select="node_a" />
							</xsl:when>
							<xsl:when test="node_b='NODE-B 2'">
								<xsl:value-of select="node_b" />
							</xsl:when>
						</xsl:choose>
					</xsl:for-each>
				</pre>
			</body>
		</html>
	</xsl:template>
</xsl:stylesheet>

concat.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<html>
			<body>
				<pre>
					<xsl:for-each select="root/element">
						<p>
							<xsl:value-of select="concat(node_a, '&#xa;', node_b)" />
						</p>
					</xsl:for-each>
				</pre>
			</body>
		</html>
	</xsl:template>
</xsl:stylesheet>

Kanske får du lite uppslag. :)

newbergMedlem sedan nov. 201040 inlägg
#50

Jag vet inte om jag behöver konkatenera. Jag trodde att en concat skulle kunna vara en bra lösning för att det ska skrivas varannan node-a och varannan node-b.

Jag provade din choose-sats, men jag lyckas inte få något utskrivet. Ska den skriva ut varannan förresten?
Jag filtrerar ut vad jag ska skriva ut, baserat på vad innehållet i 'Tag' är.
Om värdet i 'Tag' är 1 så ska jag skriva ut värdet för 'Data'.

Och där ska jag alltså filtrera ut två olika värden på 'Tag', 1 och 2.
Om de värdena matchar så ska jag skriva ut den tillhörande 'Data' för respektive 'Tag'. Och det måste ske varannan 'Tag'-värde=1 och värde=2.

Den riktiga xml:en innehåller förstås många fler 'DataRow' med andra värden än 1 el 2.

Här är den exakta xml:en

 
<X>
  <XX>
       <DataRow>
            <Tag>Ett_värde</Tag> 
            <Data>Ett_värde</Data> 
       </DataRow>
       <DataRow>
            <Tag>Ett_värde</Tag> 
            <Data>Ett_värde</Data> 
       </DataRow>
 </XX>
</X>
SPiNMedlem sedan mars 20007 896 inlägg
#51

Körde du min XSL och XML som den var? Den fungerar nämligen fint här, och det är standard XSLT 1.0 som används.

Ang. problemet: Du vill alltså skriva ut data beroende på en tagg - så det är 'choose' du ska använda:

<xsl:for-each select="X/XX/DataRow">
    <xsl:choose>
        <!-- Om Tag == 1 eller Tag == 2 så skriver vi ut värdet på Data //-->
        <xsl:when test="Tag='1' or Tag='2'">
            <xsl:value-of select="Data" />
        </xsl:when>
    </xsl:choose>
</xsl:for-each>
newbergMedlem sedan nov. 201040 inlägg
#52

Den accepterar koden, men det skrivs inte ut något.
Jag skriver exakt som du gör ovan.
Har dubbelkollat efter slarvfel, men koden ser fan i mig ut som den ska.

SPiNMedlem sedan mars 20007 896 inlägg
#53

Det låter som att sökvägen till elementen är fel. Hur ser din template-select ut, matchar du den mot roten? (/)

newbergMedlem sedan nov. 201040 inlägg
#54

Jag har ett "huvud-template" som matchar root. Sedan i det så har jag gjort templats med name som jag anropar via call-template inuti huvud-template.

Har ju funkat med massa annan kod och templats på detta sätt åtminstone.

newbergMedlem sedan nov. 201040 inlägg
#55

Hej igen Spin (och alla andra)!
Problemet är löst, det blev en variant av din choose-sats ovan, men något modifierad.

MEN, såklart så har ett nytt problem dykt upp...

jag har nämnt det förut och då länkade du till två funktioner jag kunde använda mig av. Jag har försökt med dessa, men jag får det inte att fungera. Känns som att de kan vara lite väl komplexa för mig...

Problemet är alltså att jag får in en lång sträng som ska styckas. Delimitern är allt som oftast en bokstav eller en siffra, men då och då så kan än sträng se ut så här: 11111V111AAAA. Då ska jag alltså stycka vid det första A:t.
Dock så kan jag inte använda mig av A som delimiter då det även kan vara vilken annan bokstav som helst. Och jag antar att jag inte kan använda "den första bokstaven" som delimiter eftersom den första delen av strängen innehåller ett V.

Några idéer eller förslag? Finns det inga enklare sätt än de funktioner du länkade till tidigare?

SPiNMedlem sedan mars 20007 896 inlägg
#56

Jag tror att du har satt dig i en knipa som är svår att ta sig ur. Om det inte är omöjligt är det antagligen väldigt mycket jobb att få det att fungera. Tyvärr stödjer inte XSLT 1.0 reguljära uttryck (vilket XSLT 2.0 gör), så jag hade försökt få in något server-side-språk som parsar din data innan en XSL-mall gör resten av jobbet.

newbergMedlem sedan nov. 201040 inlägg
#57

Okej, skitsamma. Jag får försöka ordna det på annat sätt.
Dock så behöver jag högerställa ett numeriskt värde som börjar på position 11 i en sträng. Försöker få till det med din utmärkta kod som du postade för ett tag sen, men utan lycka. Notera att jag satt 11 i substringen, trodde det skulle göra susen, men icke.

<xsl:variable name="length" select="16 - string-length(MTCommon/DataRow[Tag='60M']/Data)" />
<xsl:value-of select="substring($zeroes, 11, $length)" />
<xsl:value-of select="MTCommon/DataRow[Tag='60M']/Data" />

Några idéer?

newbergMedlem sedan nov. 201040 inlägg
#58

Tror jag löste det genom att köra en avslutande substring istället för en vanlig select!

newbergMedlem sedan nov. 201040 inlägg
#59

Om jag har en sträng som kan se ut på följande två sätt:
xxxYYxxx eller xxxYxxx

Y kan ha värdet C, D, RC eller RD.

Det jag vill göra är att om Y bara är en karaktar så ska jag padda med ett space och om Y är två karaktärer så ska jag bara skriva ut det.

Någon idé?

newbergMedlem sedan nov. 201040 inlägg
#60

Försökte hårdkoda in det på följande vis, men utan lycka.

<xsl:if test="substring(matches('C', 'C'), 7, 7)">
<xsl:value-of select="substring(MTCommon/DataRow[Tag='61']/Data, 7, 7)" />
<xsl:text>&#160;</xsl:text>  
</xsl:if>

Sökvägen är definierad ovanför i en for-each.

142 ms totalt · 3 externa anrop · v20260731065814-full.91fd2ad2
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)