This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: remove blank xmlns


Hi Paul,

> I'm pretty new at the xsl thing and am having trouble fitting your
> suggestion into my existing xsl. It seems to me I would need to
> include the code within the <xsl:template
> match="p:current_projects"> or in the <xsl:for-each
> select="p:project">. But as I understand, <xsl:template match="">
> cannot be nested within another template (not sure exactly how that
> works). If you could kick me a little more in the right direction,
> that would be great. You have helped me tremendously in the past and
> your help is greatly appreciated.

You're right that templates can't be nested.

The root of your problem is that while it looks to you as if your XML
is just suffering from an extraneous attribute, actually the fact that
the attribute is a namespace declaration means that the source XML you
have differs significantly from the source XML that your stylesheet is
expecting. It's not just a matter of ignoring that attribute, you have
to somehow move the elements that are in the wrong namespace into the
right one.

Once again, the *best* way to fix the problem is to create elements in
the right namespace in the first place.

The XSLT solution that I was suggesting was that *before* you pass the
XML into your main stylesheet, you run it through a filtering
stylesheet that adjusts the XML so that it uses the namespaces that
your XSLT stylesheet is expecting. In other words, make it a two-stage
process:

XML with no --> (filtering  --> XML with  --> (your       --> result
namespace       stylesheet)     namespace     stylesheet)

Of course you don't have to use a stylesheet to do this filtering -
you could edit the XML string in the ASP or you could use a SAX filter
or something. You asked for an XSLT solution, that's all.

If you're prepared to use an extension function, you could do both
XSLT processes in a single stylesheet by creating a result tree
fragment by applying templates in 'filter' mode, convert that to a
node set, and then apply templates to it to get the output that you're
after. Add a mode attribute equal to 'main' to your current template
matching the root node, and then add a different one instead:

<xsl:template match="/">
  <xsl:variable name="filtered-xml">
    <xsl:apply-templates mode="filter" />
  </xsl:variable>
  <xsl:apply-templates select="msxsl:node-set($filtered-xml)" />
</xsl:template>

Take the templates that I sent in the last email and add mode
attributes to them with the value 'filter', and add them to your
stylesheet. Also add the msxsl namespace declaration, and you should
be away (I'm assuming you're using MSXML since you're using ASP).

Your other option is to go through your existing stylesheet and
wherever you have something that uses the 'p' prefix, like:

  p:project

change it to test the local name of the element instead, ignoring the
namespace that it belongs to:

  *[local-name() = 'project']

That way it doesn't matter what namespace the element is in, it will
be matched or selected. But this latter option is a lot more work for
the processor and makes you code a lot harder to understand as well.
You really will reap dividends by addressing the problem early in your
application rather than bending over backwards to get your stylesheet
to cope with messy input.

I hope that's a helpful kick :)

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]