Member Avatar for Member #746260

I'm doing a project for my class and one of the goals is to transform one XML to other using XSLT.
I kinda managed to obtain the info within the original XML file but I don't know why I can't "print" the tag's.

XML file (original):

<?xml version="1.0" encoding="ISO-8859-1"?>

<?xml-stylesheet type="text/xsl" href = "fotografiasXSLT1.xsl"?>
<Albuns xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" fotografiasXSD.xsd">
    <Album ID="3">
        <Dono dono="Daniel Bastos" />
        <NomeAlbum nomeAlbum="Artbook" />
        <DataCriacao>2013-06-10</DataCriacao><!-->formato das datas: YYYY-MM-DD<-->
        <DataModificacao>2013-08-16</DataModificacao>
        <Descricao descricao="PhotoShop Covers" />
        <Fotografias>
            <Fotografia FotografiaID="9">
                <NomeFotografia nomeFotografia="Cover Psicose 2.0 (com frase).png" />
                <link>http://goo.gl/XQ1GJv</link>
                <DataCriacao>2012-09-06</DataCriacao>
                <HorasCriacao>17:39:59</HorasCriacao>
                <Tipo ficheiro="png" />
                <Autor autor="Daniel Bastos" />
                <Localizacao>
                    <Cidade>Maia</Cidade>
                    <Pais>Portugal</Pais>
                </Localizacao>
                <Dimensoes>
                    <Largura>1050</Largura>
                    <Altura>1680</Altura>
                </Dimensoes>
                <TamanhoFotografia>1.34</TamanhoFotografia>
            </Fotografia>            
        </Fotografias>
    </Album>
</Albuns>

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?><!-- DWXMLSource="fotografiasXML.xml" -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>

    <xsl:template match="/Fotografias">
        <xsl:copy>
            <Fotografias>
                <xsl:apply-templates select="Fotografia/*"/>
            </Fotografias>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/*">
        <xsl:copy>
            <Fotografia>
                <xsl:value-of select="."/>
            </Fotografia>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/nomeFotografia">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/link">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/dataCriacao">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/horaCriacao">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/tipo">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/autor">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/localizacao">
        <xsl:copy>
                <xsl:apply-templates select="localizacao/*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/localizacao/*">
        <xsl:copy>
                <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/localizacao/cidade">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/localizacao/pais">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/dimensoes">
        <xsl:copy>
                <xsl:apply-templates select="dimensoes/*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/dimensoes/*">
        <xsl:copy>
                <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/dimensoes/largura">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/dimensoes/altura">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Fotografia/tamanhoFotografia">
        <xsl:copy>
            <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

XML (output):

<?xml version="1.0" encoding="ISO-8859-1"?>



        2013-06-10
        2013-08-16




                http://goo.gl/XQ1GJv
                2012-09-06
                17:39:59



                    Maia
                    Portugal


                    1050
                    1680

                1.34

Can anyone show me what I'm doing wrong or sugest something?
Thanks in advance (ps.: I'm portuguese so don't find odd if the tag names are in portuguese :b and sorry for the long post :c)

Dani AI

Generated

Two things were going on: the source XML uses a default namespace and XML names are case-sensitive. Because your XSLT used unprefixed names like /Fotografias and templates such as Fotografia/*, none of those templates matched the names in the input (which are bound to the namespace and use exact capitalization). When no matching template exists, the XSLT processor falls back to the built‑in templates, which walk the tree and output text nodes — that’s why you saw the values but no element tags.

A simple namespace-aware fix is to declare the source namespace with a prefix and use that prefix in your match/select expressions. Example (minimal, not identical to earlier snippets):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:l="http://www.dei.isep.ipp.pt/lprog"
                version="1.0" exclude-result-prefixes="l">
  <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>
  <xsl:template match="/">
    <Fotografias>
      <xsl:copy-of select="//l:Fotografia"/>
    </Fotografias>
  </xsl:template>
</xsl:stylesheet>

If the goal is to produce output elements in no namespace (so the result has plain tags, not names in the source namespace), rebuild elements using their local names. This pattern recreates elements without copying the source namespace:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="@*|text()|comment()|processing-instruction()">
    <xsl:copy/>
  </xsl:template>
</xsl:stylesheet>

Practical tips: double-check element name capitalization and attribute vs element usage (attributes use @name in XPath), use exclude-result-prefixes for prefixes you only need for matching, and test with a tiny stylesheet (or xsl:message) to confirm a template is matched. As pointed out, declaring and using a prefix for the http://www.dei.isep.ipp.pt/lprog namespace is the usual, clean fix for this kind of problem.

Further reading: Namespaces in XML 1.0 and XSLT 1.0 specification.

Recommended Answers

All 4 Replies

a result which I mean to output xml

I gave you an example generated
think of namespace

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- DWXMLSource="fotografiasXML.xml" -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:a="">
    <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>
    <xsl:template match="a:Albuns">
        <xsl:apply-templates select="a:Album"/>
    </xsl:template>
    <xsl:template match="a:Album">
        <xsl:apply-templates select="a:Fotografias"/>
    </xsl:template>
    <xsl:template match="a:Fotografias">
        <xsl:copy-of select="a:Fotografia"/>
    </xsl:template>
</xsl:stylesheet>
Member Avatar for Member #746260

Hi!
I had been following an example I found online and it didn't used any namespaces... I thought and tried to used it but the way I had the xslt made, it would be showing the tags like this: <Fotografria xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:a=""> and I didn't want that. With what you showed me here, it works like a charm!

Thanks a lot! ;)

<Albuns xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" fotografiasXSD.xsd">

in attribut xmlns =>
""
this is your namespace

so you have define xmlns in xsl

xmlns:a=""

all tag started with a:

okay ?

Member Avatar for Member #746260

Yes, I understood. Thanks for the patience! :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.