devranred
devranred

Reputation: 15

XSLT to handle namespace prefixes with different URLs

I have incoming XML files from different systems with namespaces declared for the current version of the message.
Example: xmlns:abc="MatchingVersion_6-0"
I parse this without issue using a small XSLT sheet.

One of the feeding systems has now updated their version and is feeding with the new version namepsace:
Example: xmlns:abc="MatchingVersion_7-0"

Is there a way that I can handle BOTH types with the same stylesheet - as I still receive both versions of the XML file to the same interface which uses this stylesheet. The xpaths are all the same, the prefix is the same - but the prefix resolves to different values which causes this issue. I've looked into this and it seems possible by using [local-name] - although I was wondering if there is a better way to achieve this ? Thanks in advance !

Upvotes: 0

Views: 894

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167471

XSLT/XPath 2.0 and later allow you to use e.g. <xsl:template match="*:foo"> respectively path steps with a wild card for the namespace prefix so that would allow you to write your XSLT to cater for any namespace, just using local names for matching respectively selecting.

In XSLT 3.0 you can use shadow attributes to parameterize the xpath-default-namespace, see the section in the spec on that.

Upvotes: 0

Mike Sokolov
Mike Sokolov

Reputation: 7044

There's no good way. If you change a namespace prefix definition, and change nothing else in a document, it's as if you've started using an entirely new set of elements (for those elements in the original namespace).

Nothing in the XML-toolchain, including XSLT, gives you a good way of associating the elements in one namespace with those in another. There are inefficient solutions, like wildcards for namespaces, and local-name(), but those bypass all the things XSLT tries to do to make things run smoothly, and make your code ugly.

The best suggestion I have is to auto-generate a new XSLT for the new namespace version. You can use XSLT to operate on XSLT to do this.

Of course there might be simpler solutions if the problem is limited in scope; you can use disjunctions like this:

<xslt:template match="a1:foo|a2:foo"> ... </xslt:template>

assuming a1 and a2 are bound to the two different namespaces.

Upvotes: 1

Related Questions