Question on XSLT noNamespaceSchemaLocation - biztalk

My incoming XML has the following
<ROOT-PARENT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ASR_V3.0.1_proposed.xsd">
I am using a Inline XSLT in Scripting Functoid in BizTalk 2010
I want to navigate one of the child nodes but I am unable to get the values. Do i need to
My XSLT looks like
<EXTERNALTAG xsi:noNamespaceSchemaLocation="ASR_V3.0.1_proposed.xsd">
<xsl:for-each select ="//MILESTONES/MILESTONE">
<P><xsl:value-of select="."/></P>
</xsl:for-each>
</EXTERNALTAG>
The above doesn't seem to work. Any idea what i need to do in order to take care of the
xsi:noNamespaceSchemaLocation
Thanks in advance
Karthik

OK. If my XSLT looks like this
<EXTERNALTAG> <xsl:for-each select ="//MILESTONES/MILESTONE"> <P><xsl:value-of select="."/></P> </xsl:for-each> </EXTERNALTAG>
everything is working fine
Thanks

Related

How to get a particular child node collection from xml to xslt

I have below xml file
<htmlResponses>
<resultSet></resultSet>
<referencePoint></referencePoint>
<htmlResponse></htmlResponse>
<htmlResponse></htmlResponse>
<htmlResponse></htmlResponse>
</htmlResponses>
And I want to get node "htmlResponse" collection in a xsl variable so I can loop through it by using XSLT.
Can anyone guide me how can I achieve this?
Agreed with Hobbes, but you could do this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="responses" select="//htmlResponse"/>
<xsl:template match="/">
... do something ...
<xsl:for-each select="$responses/*">
...
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
The only use case I can think of where this makes sense is if you have a lot of data, and wish to build your node set using xsl:key and then reuse that node set multiple times.

BizTalk HIPAA EDI multi-input map doesn't generate node

I had asked this question 2 years ago (Problem with BizTalk multi-input map), but then the project was shelved and I never did any further testing. I'm having to dust it off again, with some more details and screenshots.
I have a BizTalk HIPAA solution that needs to merge an 837 claim schema with some data from our system. We're doing this with a map that has two input schemas, as shown here:
(I've greatly simplified the schemas for testing purposes).
The accepted answer to my original post (using an equal functoid and value mappers) works fine with a simple schema like I had originally shown, but fails with the actual EDI schema.
In the first input message, if IsRepriced = 1, I want to use our values for HCP_01, HCP_02, and HCP_03. If it's 0, use the values in the second message (the original 837 claim). The functoids shown work fine as long as the original 837 claim actually contains the HCP node (segment), but if it's not there I'm unable to generate one from our data.
Replacing these with a scripting functoid using some if-then-else C# code has the same effect.
So, is there a way to do this using functoids, or do I need to resort to XSLT? Unfortunately I know next to nothing about XSLT, so that's going to be difficult...
Thanks!
Edit: I would up using an Inline XSLT Call Template, with this code:
<xsl:template name="Repricing_2000B_HCP">
<xsl:param name="IsRepriced" />
<xsl:choose>
<xsl:when test="$IsRepriced='1'">
<xsl:for-each select="//InputMessagePart_1/ns0:X12_00401_837_I/ns0:TS837Q3_2000A_Loop/ns0:TS837Q3_2000B_Loop/ns0:TS837Q3_2300_Loop/ns0:HCP_ClaimPricingRepricingInformation_TS837Q3_2300">
<xsl:element name="ns0:HCP_ClaimPricingRepricingInformation_TS837Q3_2300">
<xsl:copy-of select="./#*" />
<xsl:copy-of select="./*" />
</xsl:element>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="//InputMessagePart_0/ns0:X12_00401_837_I/ns0:TS837Q3_2000A_Loop/ns0:TS837Q3_2000B_Loop/ns0:TS837Q3_2300_Loop/ns0:HCP_ClaimPricingRepricingInformation_TS837Q3_2300">
<xsl:element name="ns0:HCP_ClaimPricingRepricingInformation_TS837Q3_2300">
<xsl:copy-of select="./#*" />
<xsl:copy-of select="./*" />
</xsl:element>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
I frequently hit a brick wall with with the if missing-else paradign in a Map. Sometimes Looping Functioids do the trick, sometimes not. Sometimes a carefully placed Logical Existence -> Not works, sometimes no.
It's mostly because if one of the source Records is minOccurs=0, the Mapper will wrap everything in a for-each. Since the Element doesn't exist, the code never gets executed.
I'd say >50%, I resort to inline Xslt because at some point, it becomes cleaner than a page of mostly duplicate Functoid groups.
However, I'd bet the Xslt won't turn out as difficult a proposition as you think. The Mapper can do most of the work for you. You can build the bulk of the Map using Functoids, then just copy the resulting Xslt. You will have to modify for some things, like namespaces.
(Same answer)

XSLT crashes when encountering Ampersand sign

I am currently running in some trouble when trying to output a certain XML tag containing the Ampersand sign (&).
So more concrete, when I try to output the following tag. I get an error
<fullname>Ben & Jerry</fullname>
Using the following tag however runs just fine
<fullname>Ben and Jerry</fullname>
I have tried it with the following code
<xsl:template match="fullname">
<xsl:apply-templates/>
</xsl:template>
And I also tried
<xsl:template match="fullname">
<xsl:value-of-select="." disable-output-escaping="Yes"/>
</xsl:template>
Both resulted in an error. The only way how I get it to work is by using CDATA like this
<fullname><![CDATA[Ben & Jerry]]></fullname>
However, I have no control over the XML files I receive, and as such this is not a viable option. Is there something I can do within the XSLT to circumvent/fix this problem?
Thanks!
Ampersand can't appear as itself in well-formed XML. Your example should be
<fullname>Ben & Jerry</fullname>
I don't think you'll be able to get around this with any XSLT processor. You need to fix whatever generates the XML so it is well-formed.
So more concrete, when I try to output the following tag. I get an
error
<fullname>Ben & Jerry</fullname>
Actually, this isn't a tag. It's a start tag followed by some invalid content followed by an end tag.
You can't output invalid content using XSLT. If you have to output something that isn't XML, you'll need to use a non-XML tool to do it. And you're more likely to get advice on a non-XML forum.
What you haven't made clear is exactly what your input and output are. You say you are trying to output invalid XML, but you don't say what the input is.

css select xml value and print

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="tibu.css"?>
<THREADS>
<thread address="0011">
<sms msgBox="inbox" date="2012-10-30T06:49:36.529Z" locked="false" seen="true" read="true" serviceCenter="121212" address="0011" encoding="plain">aaaa</sms>
</thread>
<thread address="0123">
<sms msgBox="inbox" date="2012-10-30T06:49:36.529Z" locked="false" seen="true" read="true" serviceCenter="121212" address="0123" encoding="plain">Bugbug</sms>
</thread>
</THREADS>
Is it possible to select the date value and then print it?
If "yes" how can i do it?
I don't think CSS can do this, or if it can it isn't the best tool for the job
Take a look at XSL Transformations
XSLT is used to transform an XML document into another XML document, or another type of document that is recognized by a browser, like HTML and XHTML. Normally XSLT does this by transforming each XML element into an (X)HTML element.
Very good resource and tutorials
http://www.w3schools.com/xsl/

How would I dynamically add a new XML node based on the values of other nodes?

Background:
I have an old web CMS that stored content in XML files, one XML file per page. I am in the process of importing content from that CMS into a new one, and I know I'm going to need to massage the existing XML in order for the import process to work properly.
Existing XML:
<page>
<audience1>true</audience>
<audience2>false</audience>
<audience3>true</audience>
<audience4>false</audience>
<audience5>true</audience>
</page>
Desired XML:
<page>
<audience1>true</audience>
<audience2>false</audience>
<audience3>true</audience>
<audience4>false</audience>
<audience5>true</audience>
<audiences>1,3,5</audiences>
</page>
Question:
The desired XML adds the node, with a comma-delimited list of the other nodes that have a "true" value. I need to achieve the desired XML for several files, so what is the best way to accomplish this? Some of my ideas:
Use a text editor with a regex find/replace. But what expression? I wouldn't even know where to begin.
Use a programming language like ASP.NET to parse the files and append the desired node. Again, not sure where to begin here as my .NET skills are only average.
Suggestions?
I would probably use the XmlDocument class in .net, but that's just me because I've never been that fond of regexs.
You could then use XPath expressions to pull out the child nodes of each page node, evaluate them, and append a new node at the end of the page children, save the XmlDocument when you are done.
Xsl is an option too, but the initial learning curve is a bit painful.
There's probably a more elegant way with a regex, but if you are only running it once, it only matters that it works.
I would likely use an XSLT stylesheet to solve this problem. I built the following stylesheet to be a little bit generic that exactly what you asked for, but it could easily be modified to give you the exact output you had specified if you truly need that exact output.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="/*"/>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:element name="nodes">
<xsl:apply-templates select="*[normalize-space(.) = 'true']"/>
</xsl:element>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*">
<xsl:value-of select="concat(',', local-name())"/>
</xsl:template>
<xsl:template match="/*/*[1]">
<xsl:value-of select="local-name()"/>
</xsl:template>
</xsl:stylesheet>
This XSLT's output would be:
<page>
<audience1>
true
</audience1>
<audience2>
false
</audience2>
<audience3>
true
</audience3>
<audience4>
false
</audience4>
<audience5>
true
</audience5>
<nodes>audience1,audience3,audience5</nodes>
</page>
XSLT would be a good fit for this because you can use from almost any programming language you want or you could use Visual Studio to apply the template. There are also many free tools out there that you could use to apply the transformations.

Resources