Regex reverse lookup in xsl matches function - regex

I am trying to identify phone numbers that do not match certain criteria. Among oher things, I want to match international numbers that are not French (ie not +33 nor 0033). I have a regex that uses a reverse lookup (ie "?!") to say "not 33" which works when I test it alone. However when I try to use it in an xsl stylesheet I get an error "Invalid regular expression FORX0002".
Here is the part of my Regex that is causing me problems
^((\+|00)(?!33)[1-9]\d{0,2})\D?(\d\D?){9,14}$
Simplified stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fo fn xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<root class="object">
<contacts class="array">
<xsl:for-each select="//row">
<row>
<xsl:if test="not(matches(., '^((\+|00)(?!33)[1-9]\d{0,2})\D?(\d\D?){9,14}$'))">
<Business_Phone>
<xsl:value-of select="."/>
</Business_Phone>
</xsl:if>
</row>
</xsl:for-each>
</contacts>
</root>
</xsl:template>
</xsl:stylesheet>
Sample data:
<?xml version="1.0" encoding="utf-8"?>
<root>
<row>
<Identifier>02</Identifier>
<Name>John Doe</Name>
<Business_Phone>+34 67.89</Business_Phone>
</row>
<row>
<Identifier>03</Identifier>
<Name>Jim Doe</Name>
<Business_Phone>+33 123 456 789</Business_Phone>
</row>
</root>
With this sample I am expecting to get:
<root class="object">
<contacts class="array">
<row>
<Identifier class="string">02</Identifier>
<Business_Phone>+34 67.89</Business_Phone>
</row>
</contacts>
</root>
Is there a syntax I can use to make this work?
Many thanks

Related

Sum for distinct employee using xslt

I have a xml as below:
<root>
<row>
<Leave_days>6</Leave_days>
<Maximum>10</Maximum>
<Employee>John</Employee>
</row>
<row>
<Leave_days>4</Leave_days>
<Maximum>15</Maximum>
<Employee>Albert</Employee>
</row>
<row>
<Leave_days>2</Leave_days>
<Maximum>10</Maximum>
<Employee>John</Employee>
</row>
</root>
I need to sum the 'Maximum' but not consider the repeating employee. So for the example above, the output should be 25 (10 for John and 15 for Albert - should ignore the 2nd row for John as it is repeating)
<Root>
<row>25</row>
</Root>
In the below xslt, I'm not sure how to add a condition to eliminate the repeating employee row:
<xsl:template match="root">
<Root>
<row>
<xsl:value-of select="sum(row/Maximum)"/>
</row>
</Root>
</xsl:template>
Also tried with group-by but not able to achieve the result. Please help.
I believe the simplest solution - even in XSLT 2.0 - would be to use the Muenchian grouping expression to select the distinct employee rows:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="row-by-emp" match="row" use="Employee" />
<xsl:template match="/root">
<Root>
<row>
<xsl:value-of select="sum(row[count(. | key('row-by-emp', Employee)[1]) = 1]/Maximum)"/>
</row>
</Root>
</xsl:template>
</xsl:stylesheet>
To do this with XSLT 2.0 group-by you'd need something like:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<xsl:variable name="maxima">
<xsl:for-each-group select="row" group-by="Employee">
<xsl:copy-of select="Maximum"/>
</xsl:for-each-group>
</xsl:variable>
<Root>
<row>
<xsl:value-of select="sum($maxima/Maximum)"/>
</row>
</Root>
</xsl:template>
</xsl:stylesheet>

Group XML elements with comma seperated values with XSLT program

We are new to xslt programming, can you please help us with xslt program.
We need to group xml elements based on "id" tag and concatenate the other xml tag with comma.
input xml file:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<row>
<id>123</id>
<functional_manager__c.users>1234567</functional_manager__c.users>
</row>
<row>
<id>123</id>
<functional_manager__c.users>1200000</functional_manager__c.users>
</row>
<row>
<id>111</id>
<functional_manager__c.users>11111111</functional_manager__c.users>
</row>
<row>
<id>111</id>
<functional_manager__c.users>2222222</functional_manager__c.users>
</row>
<row>
<id>123</id>
<editor__v.users>1234567</editor__v.users>
</row>
<row>
<id>123</id>
<editor__v.users>1200000</editor__v.users>
</row>
<row>
<id>111</id>
<learning_partner__c.users>11111111</learning_partner__c.users>
</row>
<row>
<id>111</id>
<learning_partner__c.users>2222222</learning_partner__c.users>
</row>
</root>
Required Output:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<row>
<id>123</id>
<functional_manager__c.users>1234567,1200000</functional_manager__c.users>
</row>
<row>
<id>111</id>
<functional_manager__c.users>11111111,2222222</functional_manager__c.users>
</row>
<row>
<id>123</id>
<editor__v.users>1234567,1200000</editor__v.users>
</row>
<row>
<id>111</id>
<learning_partner__c.users>11111111,2222222</learning_partner__c.users>
</row>
</root>
code we tried:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xsl wd xsd this env"
xmlns:wd="urn:com.workday/bsvc"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:this="urn:this-stylesheet">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="/">
<Sharingsettings>
<xsl:for-each-group select="/root/row" group-by="id">
<row>
<ID>
<xsl:value-of select="id"/>
</ID>
<functional_manager__c.users>
<xsl:value-of select="//current-group()//functional_manager__c.users">
</xsl:value-of>
</functional_manager__c.users>
</row>
</xsl:for-each-group>
</Sharingsettings>
</xsl:template>
</xsl:stylesheet>
we are trying with XSLT program but it is not giving required output properly.
Thank you so much in advance
With XSLT 3 you can use
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="row" group-adjacent="id">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="row/*[not(self::id)]">
<xsl:copy>
<xsl:value-of select="current-group()/*[node-name() = node-name(current())]" separator=","/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Moving similar nodes to new node using XSLT

I have the following input xml:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<PQGetCareGaps>
<METHOD>GET</METHOD>
<contract>HXXXX</contract>
</PQGetCareGaps>
<FinalCareGapResults>
<Gap>
<CareGap>Colorectal Cancer Screening</CareGap>
<GapHistory>
<row>
<MEMBERID>AAAAAA000016-00</MEMBERID>
</row>
</GapHistory>
</Gap>
</FinalCareGapResults>
<FinalCareGapResults>
<Gap>
<CareGap>Adult BMI Assessment</CareGap>
</Gap>
</FinalCareGapResults>
</response>
I want to modify the above xml in such a way that all the <Gap> nodes should come under a new node called <TestResults>. The resultant xml should look like below:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<PQGetCareGaps>
<METHOD>GET</METHOD>
<contract>HXXXX</contract>
</PQGetCareGaps>
<TestResults>
<Gap>
<CareGap>Colorectal Cancer Screening</CareGap>
<GapHistory>
<row>
<MEMBERID>AAAAAA000016-00</MEMBERID>
</row>
</GapHistory>
</Gap>
<Gap>
<CareGap>Adult BMI Assessment</CareGap>
</Gap>
</TestResults>
</response>
Could you please help me out?
Try this
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:template match="/">
<xsl:apply-templates select="response" />
</xsl:template>
<xsl:template match="response">
<response>
<xsl:copy-of select="PQGetCareGaps" />
<TestResults>
<xsl:for-each select="FinalCareGapResults/Gap">
<xsl:copy-of select="." />
</xsl:for-each>
</TestResults>
</response>
</xsl:template>
</xsl:stylesheet>

Importing OAI source into Filemaker

I have a problem with importing an OAI source into Filemaker. The mapping is ok but the result is empty.
This is the source:
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://dublincore.org/documents/dcmi-namespace/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<responseDate>2015-01-15T12:05:11Z</responseDate>
<request verb="ListRecords" metadataPrefix="oai_dc">
http://api.memorix-maior.nl/collectiebeheer/oai-pmh/key/SORRY_THIS_KEY_I_CANNOT_SHOW/tenant/nfm
</request>
<ListRecords>
<record>
<header>
<identifier>
e:1d59bf74-a57c-11e1-af90-bf6f69fae6b6:000a80bf-e7d6-7670-b2bd-c269b2e58878
</identifier>
etc.
And this is the xslt I made:
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<ERRORCODE>0</ERRORCODE>
<METADATA>
<FIELD NAME="identifier" TYPE="TEXT"/>
</METADATA>
<RESULTSET>
<xsl:for-each select="OAI-PMH/ListRecords/record">
<ROW>
<COL>
<DATA><xsl:value-of select="header/identifier"/></DATA>
</COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>
To make it clear I only pointed the first field in the OAI source.
I hope you can help me to fix this.
Best regards,
Boudewijn Ridder
The reason why your attempt doesn't work is that the source XML nodes are in a namespace. You must declare this namespace in your stylesheet, assign it a prefix and use that prefix when addressing the nodes:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:oai="http://www.openarchives.org/OAI/2.0/">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<METADATA>
<FIELD NAME="identifier" TYPE="TEXT"/>
</METADATA>
<RESULTSET>
<xsl:for-each select="oai:OAI-PMH/oai:ListRecords/oai:record">
<ROW>
<COL>
<DATA><xsl:value-of select="oai:header/oai:identifier"/></DATA>
</COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>
Note:
If your input example is representative, you might want to use :
<xsl:value-of select="normalize-space(oai:header/oai:identifier)"/>
to trim the extraneous whitespace from the result.

XSLT: why the XSLT is not generating output when there are only outer XSL tags

My real code is not this, but the problem that i am stating here applies to my real code.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book.child.1>
<title>charithram</title>
<author>sarika</author>
</book.child.1>
<book.child.2>
<title>doublebell</title>
<author>psudarsanan</author>
</book.child.2>
</books>
XSLT 1:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<xsl:for-each select="books/*">
<newbook>
<title>
<xsl:value-of select="title" />
</title>
</newbook>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
There in no output generated for this XSLT. I am trying using online tool: http://www.freeformatter.com/xsl-transformer.html
I could not understand what was wrong, Finally when I modified the XSLT like as written below,
XSLT 2:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<mytag>
<xsl:for-each select="books/*">
<newbook>
<title>
<xsl:value-of select="title" />
</title>
</newbook>
</xsl:for-each>
</mytag>
</xsl:template>
</xsl:stylesheet>
The output is generated in this case:
outputXML:
<?xml version="1.0" encoding="UTF-8"?>
<mytag>
<newbook>
<title>charithram</title>
</newbook>
<newbook>
<title>doublebell</title>
</newbook>
</mytag>
Can you please explain why is this behavior?
Also I don't know how exactly to ask this question, so please edit or let me know if i need to change the question title.
Your first XSLT will theoretically produce the output
<?xml version="1.0" encoding="UTF-8"?>
<newbook>
<title>charithram</title>
</newbook>
<newbook>
<title>doublebell</title>
</newbook>
But that output is not valid XML, because it has 2 root tags, which is not well-formed XML.
In this situation, you have probably the following choices
specify a root element like you did in XSLT 2
change the output from XML to TEXT, but be aware that any XML program will not be able to read the output