Changing XSLT generation in MapForce - altova

I have a strange problem. I am generating an XSD to XSD mapping in MapForce and it is valid and producing output. However when the XSLT is utilized by our DataPower folks, they are saying the namespace prefixes in the XSLT are causing the code to not find the nodes in the incoming message.
For example in the XSLT, the select is:
<xsl:for-each select="ns0:costOrderHeaderLookupResponse/return/ns1:Order">
In the incoming message, the namespace prefix is as below:
*snip*
<return>
<ns2:Order BillToID="300850001000" DocumentType="0001"....*snip*>
However MapForce is generating the output just fine with no errors even with the namespace prefix difference.
The DataPower folks are requesting that instead of the namespace prefix I customize MapForce to output the nodes like this:
/*[local-name()='Order']
I read the MapForce documentation and googled for awhile but I am not finding a way to customize XSLT output like this. It is possible for C/Java/etc but I am not finding any help on changing how the XSLT is generated.

Create a filter in MapForce and use a boolean function (like core:logical functions:equal) to check to see if the local-name of the node in the select (costOrderHeaderLookupResponse/return/Order) has a local-name equal to a constant string with value Order. The function to check for the local-name should be in the xslt:xpath functions library as local-name.
The filter should replace your connection from the Orders node to whatever node it is mapped to in the second XSD.
To see how filters work (assuming you aren't already using one to get your select) view http://manual.altova.com/Mapforce/mapforcebasic/index.html?mfffilteringdata.htm

Related

exist-db: XQuery and documents with XInclude

I'm embarking on a new project with eXist. We'll be storing a few hundred TEI XML documents that represent manuscripts. A number of things we want to capture are repetitve, mainly people and places. My colleague has asked the TEI community about strategies for representing what we want to capture and using XInclude had been suggested as a way of reducing duplication.
I've had a quick play with adding an XInclude into a document and the serialized XML does render the include XML file. However, the included text was missing from an XQuery. I notice in the eXist docs (http://exist-db.org/exist/apps/doc/xinclude.xml) that:
eXist-db expands XIncludes at serialization time, which means that the
query engine will see the XInclude tags before they are expanded. You
therefore cannot query across XIncludes - unless you create your own
code (e.g. an XQuery function) for it. We would certainly like to
support queries over xincluded content in the future though.
What is the best practice for querying files that use XInclude?
I'm wondering whether I should have a 'job' that serializes the source TEI XML files to expand the XIncludes and store these files in a separate collection? In that case, would file:serialize be the correct function for this task?
We are at the start of the project, so any advice appreciated.
Can you describe what kind of query you tried that was missing the text?
Generally, since the files referenced via XInclude are well-formed xml documents, you can use collections (folders) to organise your queries in exist-db. So instead of for $search in doc("mydoc.xml") you could for $search in collection('/app/mydata')/*
more elaborate answers would follow the attribute of the unexpanded xinclude statement in source document and find the matching element in the target, but its difficult to abstract that without a concrete MWE.
have you tried to create a temporary and expanded fragment in a let clause, and query that instead of the stored xml?
Beware of namespaces !
Hope this helps, and greetings to Sebastiaan.

XPath - Select a node based on sibling node's value while using local-name()

For reasons out of scope for this question I need to be able to handle multiple xml documents of the same structure but belonging to different namespaces (don't ask).
To achieve this I've become very accustomed to using an xpath like the following for many of my value selections:
//*[local-name()='apple']/*[local-name()='flavor']/text()"
My lack of understanding of predicates is preventing me from selecting a node's value based upon a sibling node's value. Consider the following xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<fruit>
<apple>
<kind>Red Delicious</kind>
<flavor>starchy</flavor>
</apple>
<apple>
<kind>Granny Smith</kind>
<flavor>tart</flavor>
</apple>
<apple>
<kind>Pink Lady</kind>
<flavor>sweet</flavor>
</apple>
</fruit>
Let's say I want to write an xpath that will select the flavor of a Granny Smith apple. While I would normally do something like:
//apple[kind/text()='Granny Smith']/flavor/text()
I cannot figure out how to merge the concept of utilizing local-name() to be namespace agnostic while still selecting a node based upon a sibling's value.
In short, what is the xpath necessary to return "tart" regardless of what namespace the input fruit xml document belongs to?
I need to be able to handle multiple xml documents of the same
structure but belonging to different namespaces (don't ask)
My preferred way to handle this is to first transform the data to use a single namespace, and then do the transformation proper. Doing it this way (a) keeps the real transformation much simpler, (b) puts all the namespace conversion logic in one place, and (c) makes the namespace conversion logic reusable - you can use the same transformation regardless how the data will subsequently be used.

Using Boost Property Tree to replace DOM Parser

I need to write a XML Parser using Boost Property tree which can replace an existing MSXML DOM Parser. Basically my code should return the list of child nodes, number of child nodes etc. Can this be achieved using Property Tree? Eg. GetfirstChild(),selectNodes(),Getlength()etc.
I saw a lot of APIs related to Boost Property Tree, but the documentation seems to be bare minimum and confusing. As of now, I am able to parse the entire XML using BOOST_FOREACH. But the path to each node is hard coded which will not serve my purpose.
boost::property_tree can be used to parse XML and it's a tree so you can use as XML DOM substitution but the library is not intended to be fully fledged XML parser and it's not complaint with XML standard. For instance it can successfully parse non-wellformed xml input and it doesn't support some of XML features. So it's your choice - if you want simple interface to simple XML configuration then yes, you should use boost::property_tree

Can't find nodes in Atom with Ruby LibXML

I have the following XML Document:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\" xmlns:apps=\"http://schemas.google.com/apps/2006\" xmlns:gd=\"http://schemas.google.com/g/2005\">
<apps:property name=\"memberId\" value=\"Tom\"/>
</atom:entry>
All I'm trying to do is get the apps:property node. However everything I try in LibXML returns nothing.
From reading the LibXML documentation here for LibXML::XML::XPath. I would assume that I don't need to specify the two namespaces since they are defined on the root node.
Here is what I've tried:
#document.find('/apps:property')
#document.find('//apps:property')
#document.find('/atom:entry/apps:property')
#document.find('//atom:entry/apps:property')
#document.find('/property')
#document.find('/atom:entry')
#document.find('//property')
#document.find('/entry')
None of the above return a result with the specified document. I've tried them all with different combinations of the atom and apps namespace definitions as well but it doesn't seem to have an effect.
If anyone could show me what very simple thing I must be missing it would be much appreciated.
It turns out that the problem stems from the document being created dynamically rather than being read from a file.
When I write the document to a file and read it in I can search it. When I create the document, create the root element and add the child programmatically I get nil every time I try to search, oddly enough each works just fine. Do I have to "finalize" or do some other stupid thing to the document somehow before I can search it?
If I explicitly parse the document then I can search it.
Looks like that might be the solution unless it's possible for the parse tree to be generated as the document is built.
Time to look at the code I suppose.

XPATH remove attribute

Hi does anyone know hwo to remove an attrbute using xpath. In particular the rel attribute and its text from a link. i.e. <a href='http://google.com' rel='some text'>Link</a> and i want to remove rel='some text'.
There will be multiple links in the html i am parsing.
You can select items using xpath, but that's all it can do - it is a query language.
You need to use XSLT or an XML parser in order to remove attributes/elements.
As pointed out by Oded, Xpath merely identifies XML nodes. To remove/edit XML, you need some additional tooling.
One solution is the Ant-based plugin XMLTask (disclaimer - I wrote this). It provides a simple mechanism to read an XML file, identify parts of that using XPath, and change it (including removing nodes).
e.g.
<remove path="web/servlet/context[#id='redundant']"/>
Have you already tried using Javascript for this If that is applicable in your scenario:-
var allLinks=document.getElementsByTagName("a");
for(i=0;i<allLinks.length;i++)
{
allLinks[i].removeAttribute("rel");
}

Resources