BizTalk
(1)
XSLT
(1)
CXML
(1)
XML
(1)
LinkTo
(1)
DougI
(1)
URI
(1)
XSL
(1)

Handling xml:lang attributes

Asked By dou
07-Jun-07 11:04 AM
We receive cXML documents from trading partners that include xml:lang
attributes. The cXML schema defines these as mandatory and we have no control
over the attribute prefix (xml).

We've got as far as downloading then importing the W3C schema that defines
the "lang" attribute, so we can validate incoming documents. Note that when
we use the "Imports" dialog to define the import, we select the W3C schema
which sets the Namespace and Location fields, then enter "xml" for the Prefix
field. However, when the schema is saved then re-opened the Prefix field is
blank. This may (or may not!) be relevent to the next bit.

We need to map the inbound document to an outbound document (still cXML),
and this involves mapping some of the attributes over. However, the mapper
insists on creating an outbound document in which the "lang" attributes have
the prefix "ns0", and it adds a namespace prefix declaration to the root
node. Perhaps because the Prefix is blank it thinks it must create one, even
though the namespace is the standard http://www.w3.org/XML/1998/namespace.

Rather than include the whole cXML schema, I've created a simple project
which demonstrates the problem.

There is a single schema:

xmlns:xs="http://www.w3.org/2001/XMLSchema">
namespace="http://www.w3.org/XML/1998/namespace" />

which imports the W3C schema, saved as xml.xsd. I've removed all of the
annotation for brevity, but the original can be found at
http://www.w3.org/2005/08/xml.xsd.

xmlns="http://www.w3.org/XML/1998/namespace"
targetNamespace="http://www.w3.org/XML/1998/namespace" xml:lang="en"
xmlns:xs="http://www.w3.org/2001/XMLSchema">

Finally, a map just copies the Description element and lang attribute
contents over:

Version="2" XRange="100" YRange="420" OmitXmlDeclaration="Yes"
TreatElementsAsRecords="No" OptimizeValueMapping="Yes"
GenerateDefaultFixedNodes="Yes" CopyPIs="No" method="xml" xmlVersion="1.0"
indent="yes" IgnoreNamespacesForLinks="Yes">
LinkFrom="/*[local-name()='<Schema>']/*[local-name()='Test']/*[local-name()='Description']"
LinkTo="/*[local-name()='<Schema>']/*[local-name()='Test']/*[local-name()='Description']" Label="" />
LinkFrom="/*[local-name()='<Schema>']/*[local-name()='Test']/*[local-name()='Description']/@*[local-name()='lang']"
LinkTo="/*[local-name()='<Schema>']/*[local-name()='Test']/*[local-name()='Description']/@*[local-name()='lang']" Label="" />

I just wired up a send port to a receive port, and included the above map in
the send port. The sample xml document below, which validates using the above
schema, is submitted:


The output is:

xmlns:ns0="http://www.w3.org/XML/1998/namespace">

which does not validate!

We expected the output to be identical to the input, with the "lang"
attribute having the "xml" prefix.

I can sort of understand why BizTalk includes a prefix declaration in the
output because, if the prefix was anything other than "xml", for example
as that's what we are being sent.

I guess there would be a solution using custom pipeline components, but I'm
keen to pursue a simpler solution first.

Anyone had experience with this? Anyone got a solution?? Thanks in advance
for any suggestions.

--

Doug

I have a number of work arounds, but none are very good.

Asked By dou
14-Jun-07 09:56 AM
I have a number of work arounds, but none are very good.

BizTalk produces the following XSLT code from the map:

xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var" version="1.0"
xmlns:ns0="http://www.w3.org/XML/1998/namespace">
indent="yes" />

You can see what the problem is! Rather unhelpfully, BizTalk has added the
standard one for the "xml" prefix, i.e.

Workaround 1. Add the namespace declaration
xmlns:xml="http://www.w3.org/XML/1998/namespace" to the schema in a text
editor. Everything then works OK, but if the schema is re-saved in VS it
removes it again!

Workaround 2. Change all occurences of "ns0" to "xml" in the above XSLT and
save it away. Then create and use a BizTalk map with the "Custom XSL Path"
property pointing to the modified XSLT. This also works OK, but if the
BizTalk map is changed we need to remember to drop out the XSLT.

Workaround 3. Use in-line XSLT scripting to create the xml:lang attributes
in the output document. This, however, still results in the outbound document
having the declaration xmlns:ns0="http://www.w3.org/XML/1998/namespace" in
the outbound document, and I don't know if this would cause problems for the
party we send the documents to.

As no-one has posted a reply I assume that either I'm being really stupid
and there's a much easier way to fix this, or that nobody else has this issue
or knows how to fix it. Hoping it's the latter, I'm going to use up a
Microsoft support call to see if it's really a bug. I'll report back any
responses here.
--

Doug
Post Question To EggHeadCafe