0

Say I have an XML file which looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<Project xmlns="http://My/Project.xsd">
    <Thing Name="test"/>
</Project>

And my XSLT is:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns="http://My/Project.xsd">
    <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>

    <xsl:template match="Thing">
        <xsl:value-of select="@Name"/>
    </xsl:template>
</xsl:stylesheet>

The output is [NewLine][Tab][NewLine] which matches the spacing of the XML file.

If I change my XSLT to be: (added a prefix)

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns:N="http://My/Project.xsd">
    <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>

    <xsl:template match="N:Thing">
        <xsl:value-of select="@Name"/>
    </xsl:template>
</xsl:stylesheet>

The output is [NewLine][Tab]test[NewLine] which again matches the spacing of the XML file but includes the value of the "Name" attribute.

My expected output is simply test. No new lines, no tabs - it should not follow the format of the XML file at all.

I want to write the XML and XSLT without using prefixes. How can I make this output what I'm expecting?

1 Answer 1

3

There are two issues here - first is that you don't want to specify the namespace prefix and second is that you don't want to have spaces from source document to affect your output. Let's discuss them separately.

Using namespace prefix: The short answer is no - you can not write XSL template that matches elements within particular namespace without specifying such namespace using prefix. In your first XSLT you could read template definition like "I want to select node named Thing which doesn't have any namespace" while what you really want to say is "I want to select node named Thing which has namespace http://My/Project.xsd". This is the way XPath 1.0 specification works (more details in this article).

Getting rid of spacing: Use <xsl:strip-space elements="*"/> instruction at the beginning of stylesheet to specify that you don't want spaces from all source elements to be preserved in output document. If you want to preserve some of them use <xsl:preserve-spaces elements="myNode"> as well.

Sign up to request clarification or add additional context in comments.

3 Comments

To add to that, the reason you are getting the whitespace is that there are built-in template rules in your stylesheet that process the nodes you aren't matching explicitly. The default rule for a text node - even a whitespace-only text node - is to copy it to the output. As well as xsl:strip-space, another way to prevent this is to add the rule <xsl:template match=text()"/>, an empty template rules which means that when the processor hits a text node, by default it ignores it.
Michael, excellent comment! And thank you for the book, btw :)
Another addition: you can select elements disregarding namespace with *[local-name()='whatever'] in XSLT/XPath 1.0 or *:whatever in XSLT/XPath 2.0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.