XSLT 2.0: Check if string within a node-set is contained in another string - xslt-2.0

I have a requirement in which the input XML that is received has different error description for the same error code. I need to compare whether a part of the text is contained within the error description in order to do some filtering. Below is the snippet of what I am trying to do.
Created a variable to store a list of all the partial text to be checked within the error description.
<xsl:variable name="partialTextList">
<errorDesc value="insufficient funds" />
<errorDesc value="amount cannot exceed" />
</xsl:variable>
Created a key to access the variable
<xsl:key name="kErrorDesc" match="errorDesc" use="#value" />
The input XML to this XSL will have something like
<Error>
<Code>123</Code>
<Desc>Transaction cannot be processed as account has insufficient funds.</Desc>
</Error>
OR
<Error>
<Code>123</Code>
<Desc>The withdrawal amount cannot exceed account balance.</Desc>
</Error>
Is it possible to use contains function to check whether <Desc> has one of the values from partialTextList?
I tried to look up a solution for this comparison but was not able to find one. Most of the solutions are to check whether <Desc> value is present in the list but not vice-versa.
Any help is appreciated.

In the context of e.g. xsl:template match="Error" you can certainly check $partialTextList/errorDesc/#value[contains(current()/Desc, .)] or move it to the pattern xsl:template match="Error[$partialTextList/errorDesc/#value[contains(current()/Desc, .)]]" if you like.

Related

SEC company filings: Is the <SEC-HEADER> tag valid SGML? If so, how to parse it?

I tried to parse SEC company filings from sec.gov. Starting from fb 10-Q index.htm let's look at a complete text submission filing like complete submission text filing. It has a structure like:
<SEC-DOCUMENT>
<SEC-HEADER>
<ACCEPTANCE-DATETIME>"some content" This tag is not closed.
"some lines resembling yaml markup"
These are indented lines with a
"key": "value" structure.
</SEC-HEADER>
<DOCUMENT>
.
.
some content
.
.
</DOCUMENT>
"several DOCUMENT tags" ...
</SEC-DOCUMENT>
I tried to figure out the structure of the <SEC-HEADER> tag and found some information under Public Dissemination
Service (PDS) Technical
Specification (pdf) and concluded that the content of the header should be SGML.
Nevertheless, I am clueless about the formatting, since there are no angle brackets, and the keys - value paires are separated by colons like key: value instead of <key>value</key>. In the pdf link I could not find anything about colons.
Question: Is the <SEC-HEADER> tag valid SGML? If it is, how to parse it?
I'd be glad at any help.
The short answer is no. The <SEC-HEADER> tag in the raw filing is not a valid SGML.
However, it is my understanding that this section in the raw filing is parsed automatically from the header file <accession_num>.hdr.sgml, which does follow SGML. This header file can be found in the same directory as the raw filing (i.e., the <accession_num>.txt file).
I use a REGEX of the form: ^<(.+?)>(.+?)$ (with re.MULTILINE option) to capture each (tag, value) tuple and get the results directly in a dict().
I believe the only tag in that file that has a closing tag is the </FILER> tag, where there could be multiple filers in each filing. You can first extract those using a REGEX of the form: <FILER>(.+?)</FILER> and then employ the same REGEX as above to get the inner tags for each filer.
Note that other than 'FILER', there could be other tags, representing different relations of the entities to the filing. Those are 'ISSUER', 'SUBJECT COMPANY', 'FILED BY', 'FILED FOR', 'SERIAL COMPANY', 'REPORTING OWNER'.

Adding a datamodule to the delphi object repository

I am using D10 Pro. I added a datamodule to the object repository by right clicking it and selecting "Add to Repository" on the popup menu.
The datamodule shows up in the New>Other dialog and I am able to click the icon for it. When I do, I get the following exception: "Unable to find both a form () and source file (). The same exception occurs with forms I place there. The object that came with Delphi load without any problem. How do I fix this?
When adding items to the repository, you should avoid using dotnet style names for your files. For example, I originally named the file "MyLib.Datamodule.TextImporter.pas" and I received the error in my question. I experienced the same problem with a form using the same dotnet style naming. After changing the file name to "TextImporterDatamodule.pas" and adding it to the repository, I was able to use it to create new datamodules without a problem. This is something Embarcadero needs to address.
I can't answer your q, but maybe this will help you track down your problem.
Contrary to what the DocWiki says for Seattle, the repository .Xml file is actually named "Repository.Xml" and in my case is located here:
C:\Users\MA\AppData\Roaming\Embarcadero\BDS\17.0\Repository.Xml
I added a data module to it, resulting in the entry shown below being added.
Notice that for a datamodule, the path to it is stored in its IDString
attribute along with the filename, unlike a form, where the path+name is stored
in the the Value attribute of the FormName node.
With that entry in place, unlike you I can then include a copy of it in a project
by going to File | New | Other in the IDE. However, if I then change the
on-disk name of the folder where the item is located, and try to use it, I get the error
message you quoted. Of course, that doesn't mean that's why you're getting
it, but I thought it might help to see the repository entry for something that's known to work.
<Item IDString="D:\Delphi\Code\SO\Devex\DM1" CreatorIDString="BorlandDelphiRepositoryCreator">
<Name Value="AAADataModule"/>
<Icon Value=""/>
<Description Value="MA datamodule"/>
<Author Value="MA"/>
<Personality Value="Delphi.Personality"/>
<Platforms Value=""/>
<Frameworks Value=""/>
<Identities Value="RADSTUDIO"/>
<Categories>
<Category Value="InternalRepositoryCategory.MyCategory" Parent="Borland.Delphi.NewFiles">MyCategory</Category>
<Category Value="Borland.Delphi.NewFiles" Parent="Borland.Delphi.New">Delphi Files</Category>
<Category Value="Borland.Delphi.New" Parent="Borland.Root">Delphi Projects</Category>
</Categories>
<Type Value="FormTemplate"/>
<Ancestor Value=""/>
<FormName Value=""/>
<Designer Value="Any"/>
</Item>
If this doesn't help, best I can suggest is to post your q in the IDE section
of EMBA's newsgroups here:
https://forums.embarcadero.com/forum.jspa?forumID=62
I don't think that should provoke cross-posting complaints, seeing as your q has been up here for a while without getting a definitive answer.

How to provide an empty Source in xslTransformer.transform() method?

I have an xslt 2.0 file which is being used to transform a csv file to an xml file. The xsl has been taken from here:
http://p2p.wrox.com/xslt/40898-transform-csv-file-xml.html#post164344
Now I am trying to execute this through Java transformer (using the Saxon9 xsl transformer factory). Since the csv file is being passed into the xsl as a parameter, there is no need for me to pass anything in the Source parameter in the transform method. Since the javadocs for the transform method state the following:
The javadocs for the Transformer.transform method clearly state that the following:
"An empty Source is represented as an empty document as constructed by DocumentBuilder.newDocument(). The result of transforming an empty Source depends on the transformation behavior; it is not always an empty Result."
I tried to create an empty document and try the transformation as seen below:
TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl",null);
Source xsltSource = new StreamSource("file:///C:/my.xsl");
Transformer xsltTransformer = transformerFactory.newTransformer(xsltSource);
xsltTransformer.setParameter("pathToCSV", "'file:///C:/input.csv'");
StringWriter writer = new StringWriter();
xsltTransformer.transform(new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()), new StreamResult(writer));
The above piece of code does not output anything and does not work as expected since I think the empty document given as input is taken into consideration rather than the csv file passed in the following line in the xsl:
<xsl:param name="pathToCSV" />
<xsl:variable name="input" select="unparsed-text($pathToCSV)"/>
Could anyone give me pointers on how to accomplish what I am trying to achieve?
Consider to use the Saxon API http://saxonica.com/documentation/html/using-xsl/embedding/s9api-transformation.html and not to use the JAXP API if you want to use XSLT 2.0 features like starting with a named template as the XSLT you linked to requires. Or, if you want to use JAXP with an empty dummy document you at least need to add a template doing
<xsl:template match="/">
<xsl:call-template name="main"/>
</xsl:template>

Mule ESB IMAP questions

Currently we need fetch mails from an IMAP server using Mule ESB. Once the mails have been fetched, we only need the attachments and save them on the harddrive. So far so good. Now I got a couple of questions:
How do I keep the original name intact using a file:outbound-endpoint?
How can I check how many attachments I got?
How do save a copy of the mail on the IMAP and local drive?
#1: I tried #header:fileName or #originalFileName or even removing the outputpattern (this results in the filename being "35c7dea0-519a-11e1-b8b2-092b658ae008.dat")
#2: I am trying to make a flow where I check how many attachments there are. If there are less then 1 then I want to save the files and no further process them. If it's more then 1, then save it and process it. I tried COUNT but it didn't work.
#3: am trying to MOVE a message when READ to a back-up folder on the IMAP-server. On top of that I'll save a copy on the local server. Problem is that with the current code, the message does not get marked as read nor moved. The messages stay unread and they get copied (over and over, enldess loop) instead of getting moved to the IMAP back-up folder. When enabling the deleteReadMessages then the loop is broken but the message does not get copied on the IMAP.
Here's the code I am currently using:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:imap="http://www.mulesoft.org/schema/mule/imap"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:email="http://www.mulesoft.org/schema/mule/email"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.2/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/3.2/mule-file.xsd
http://www.mulesoft.org/schema/mule/imap http://www.mulesoft.org/schema/mule/imap/3.2/mule-imap.xsd
http://www.mulesoft.org/schema/mule/email http://www.mulesoft.org/schema/mule/email/3.2/mule-email.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.2/mule-vm.xsd">
<imap:connector name="imapConnector" checkFrequency="5000"
backupEnabled="true" backupFolder="/home/mark/workspace/Eclipse/RHZ_Project/src/Archive/"
mailboxFolder="INBOX" moveToFolder="INBOX.Backup" deleteReadMessages="false"
defaultProcessMessageAction="SEEN" />
<expression-transformer name="returnAttachments">
<return-argument evaluator="attachments-list" expression="*.txt,*.ozb,*.xml" optional="false"/>
</expression-transformer>
<flow name="Flow1_IMAP_fetch">
<imap:inbound-endpoint user="USER" password="PASS" host="IP"
port="143" transformer-refs="returnAttachments" disableTransportTransformer="true"/>
<collection-splitter/>
<file:outbound-endpoint path="/home/mark/workspace/Eclipse/RHZ_Project/src/Inbox/#[function:datestamp].dat">
<expression-transformer>
<return-argument expression="payload.inputStream" evaluator="groovy" />
</expression-transformer>
</file:outbound-endpoint>
</flow>
</mule>
1) How do I keep the original name intact using a file:outbound-endpoint?
Attachments are javax.activation.DataHandler instances so you should be able to call getName() on them, with an OGNL or Groovy expression. For example:
#[groovy:payload.name]
Should give you the original attachment name.
2) How can I check how many attachments I got?
Before the splitter, use a choice router and an condition that checks the size() attribute of the attachment list, like:
#[groovy:payload.size()>1]
3) How do save a copy of the mail on the IMAP and local drive?
I do not know what the issue is here. Maybe marking as seen is not supported. Or maybe the fact that you disable the transport transformer prevents a post-read action to kick in.
By the way, I suggest you leave the default transport transformer as-is and move the returnAttachments transformer after the inbound endpoint, before the splitter.

What does "Error parsing XML: not well-formed" mean?

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent” >
I get these two errors
error: Error parsing XML: not well-formed (invalid token)
&
Open quote is expected for attribute "android:orientation" associated with an element type "LinearLayout".
Did you copy and paste that from word? Your quotes look a little funky. Sometimes word will use a different character than the expected " for double quotes. Make sure those are all consistent. Otherwise, the syntax is invalid.
Looks like you have "smart quotes" ( not simple " double quotes) around some attributes in your LinearLayout element.
There are many references that explain the differences between valid and well formed XML documents. A good starting point can be found here. There is also an online XML Validator that you can use to test XML documents.
The validator shows that you have two issues:
Some of your attribute values use an invalid quote character: ” vs. ", and
you need to close the LinearLayout tag with /> instead of just >.

Resources