Xml validation with xsl - java

i have been trying to validate xml through xslt for couple of hours. i have following xsl form for xml validation. every time i try to validate xml, i get following warnings below and empty currencyid attributes in xml are ignored and xml validate although its not. Does anyone has an idea why its ignored and validated ?
<xsl:variable name="CurrencyCodeList"
select="',AED,AFN,ALL,AMD,ANG,AOA,ARS,AUD,AWG,AZN,BAM,BBD,BDT,BGN,BHD,BIF,BMD,BND,BOB,BOV,BRL,BSD,BTN,BWP,BYR,BZD,CAD,CDF,CHE,CHF,CHW,CLF,CLP,CNY,COP,COU,CRC,CUC,CUP,CVE,CZK,DJF,DKK,DOP,DZD,EEK,EGP,ERN,ETB,EUR,FJD,FKP,GBP,GEL,GHS,GIP,GMD,GNF,GTQ,GWP,GYD,HKD,HNL,HRK,HTG,HUF,IDR,ILS,INR,IQD,IRR,ISK,JMD,JOD,JPY,KES,KGS,KHR,KMF,KPW,KRW,KWD,KYD,KZT,LAK,LBP,LKR,LRD,LSL,LTL,LVL,LYD,MAD,MAD,MDL,MGA,MKD,MMK,MNT,MOP,MRO,MUR,MVR,MWK,MXN,MXV,MYR,MZN,NAD,NGN,NIO,NOK,NPR,NZD,OMR,PAB,PEN,PGK,PHP,PKR,PLN,PYG,QAR,RON,RSD,RUB,RWF,SAR,SBD,SCR,SDG,SEK,SGD,SHP,SLL,SOS,SRD,STD,SVC,SYP,SZL,THB,TJS,TMT,TND,TOP,TRY,TTD,TWD,TZS,UAH,UGX,USD,USN,USS,UYI,UYU,UZS,VEF,VND,VUV,WST,XAF,XAG,XAU,XBA,XBB,XBC,XBD,XCD,XDR,XFU,XOF,XPD,XPF,XPF,XPF,XPT,XTS,XXX,YER,ZAR,ZMK,ZWL,'"/>
<xsl:template match="//#currencyID" priority="1008" mode="M0">
<svrl:fired-rule xmlns:svrl="http://purl.oclc.org/dsdl/svrl" context="//#currencyID"/>
<!--ASSERT -->
<xsl:choose>
<xsl:when test="contains($CurrencyCodeList, concat(',',.,','))"/>
<xsl:otherwise>
<svrl:failed-assert xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
test="contains($CurrencyCodeList, concat(',',.,','))">
<xsl:attribute name="location">
<xsl:apply-templates select="." mode="schematron-select-full-path"/>
</xsl:attribute>
<svrl:text>Geçersiz currencyID niteliği : '<xsl:text/>
<xsl:value-of select="."/>
<xsl:text/>'. Geçerli değerler için kod listesine bakınız.</svrl:text>
</svrl:failed-assert>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="*|comment()|processing-instruction()" mode="M0"/>
Warning: on line 286
The preceding-sibling axis starting at a namespace node will never select anything
Warning: on line 311
The preceding-sibling axis starting at a namespace node will never select anything
Warning: on line 407
The child axis starting at an attribute node will never select anything
Warning: on line 407
The child axis starting at an attribute node will never select anything
Warning: on line 407
The child axis starting at an attribute node will never select anything
Warning: on line 436
The child axis starting at an attribute node will never select anything
Warning: on line 436
The child axis starting at an attribute node will never select anything
Warning: on line 436
EDIT:
actually i transformed schematron to xslt in order to test it also in xslt. given was schematron for validating. so actually i have to validate through given schematron files, sample xml and java code for validating. main schematron and other files have more rules and patterns. but i removed most of them for sample code and easily testing. everything is validated successfully except attributes in elements.( e.g currencyId attribute). im using UgliSch (Ugli Schematron Validator) for schematron validation.
MainSchematron.xml:
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns="http://purl.oclc.org/dsdl/schematron"
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns:sh="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader"
xmlns:ef="http://www.efatura.gov.tr/envelope-namespace">
<sch:include href="UBL-TR_Codelist.xml#codes"/>
<sch:include href="UBL-TR_Common_Schematron.xml#abstracts"/>
<sch:ns prefix="cbc" uri="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" />
<sch:rule context="//cbc:CurrencyCode">
<sch:extends rule="GeneralCurrencyCodeCheck"/>
</sch:rule>
<sch:rule context="//#currencyID">
<sch:extends rule="GeneralCurrencyIDCheck"/>
</sch:rule>
</sch:schema>
UBL-TR_Common_Schematron.xml:
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns="http://purl.oclc.org/dsdl/schematron">
<sch:pattern name="AbstractRules" id="abstracts">
<sch:p>Pattern for storing abstract rules</sch:p>
<!-- Rule to validate currencyID Genel -->
<sch:rule abstract="true" id="GeneralCurrencyIDCheck">
<sch:assert test="contains($CurrencyCodeList, concat(',',.,','))">Geçersiz currencyID niteliği : '<sch:value-of select="."/>'. Geçerli değerler için kod listesine bakınız.</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
UBL-TR_Codelist.xml:
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns="http://purl.oclc.org/dsdl/schematron">
<sch:pattern name="CodeList" id="codes">
<sch:let name="CurrencyCodeList" value="',AED,AFN,ALL,AMD,ANG,AOA,ARS,AUD,AWG,AZN,BAM,BBD,BDT,BGN,BHD,BIF,BMD,BND,BOB,BOV,BRL,BSD,BTN,BWP,BYR,BZD,CAD,CDF,CHE,CHF,CHW,CLF,CLP,CNY,COP,COU,CRC,CUC,CUP,CVE,CZK,DJF,DKK,DOP,DZD,EEK,EGP,ERN,ETB,EUR,FJD,FKP,GBP,GEL,GHS,GIP,GMD,GNF,GTQ,GWP,GYD,HKD,HNL,HRK,HTG,HUF,IDR,ILS,INR,IQD,IRR,ISK,JMD,JOD,JPY,KES,KGS,KHR,KMF,KPW,KRW,KWD,KYD,KZT,LAK,LBP,LKR,LRD,LSL,LTL,LVL,LYD,MAD,MAD,MDL,MGA,MKD,MMK,MNT,MOP,MRO,MUR,MVR,MWK,MXN,MXV,MYR,MZN,NAD,NGN,NIO,NOK,NPR,NZD,OMR,PAB,PEN,PGK,PHP,PKR,PLN,PYG,QAR,RON,RSD,RUB,RWF,SAR,SBD,SCR,SDG,SEK,SGD,SHP,SLL,SOS,SRD,STD,SVC,SYP,SZL,THB,TJS,TMT,TND,TOP,TRY,TTD,TWD,TZS,UAH,UGX,USD,USN,USS,UYI,UYU,UZS,VEF,VND,VUV,WST,XAF,XAG,XAU,XBA,XBB,XBC,XBD,XCD,XDR,XFU,XOF,XPD,XPF,XPF,XPF,XPT,XTS,XXX,YER,ZAR,ZMK,ZWL,'"/>
</sch:pattern>
</sch:schema>
sample.xml:
<sh:StandardBusinessDocument xsi:schemaLocation="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader PackageProxy_1_2.xsd" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:ef="http://www.efatura.gov.tr/package-namespace" xmlns:oa="http://www.openapplications.org/oagis/9" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:sh="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ns9="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:ns11="urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2" xmlns:ns3="http://www.hr-xml.org/3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<sh:StandardBusinessDocumentHeader>
<sh:HeaderVersion>1.0</sh:HeaderVersion>
<sh:Sender>
<sh:Identifier>urn:mail:defaultgb#xxx.com.tr</sh:Identifier>
<sh:ContactInformation>
<sh:Contact>xxx Kurumsal Bilgi Sistemleri A.Ş</sh:Contact>
<sh:ContactTypeIdentifier>UNVAN</sh:ContactTypeIdentifier>
</sh:ContactInformation>
<sh:ContactInformation>
<sh:Contact>8110120507</sh:Contact>
<sh:ContactTypeIdentifier>VKN_TCKN</sh:ContactTypeIdentifier>
</sh:ContactInformation>
</sh:Sender>
<sh:Receiver>
<sh:Identifier>urn:mail:defaultpk#xxx.com.tr</sh:Identifier>
<sh:ContactInformation>
<sh:Contact>KAKAR KURUMSAL BİLGİSİSTEMLERİ LTD.ŞTİ. Test Kullanıcısı</sh:Contact>
<sh:ContactTypeIdentifier>UNVAN</sh:ContactTypeIdentifier>
</sh:ContactInformation>
<sh:ContactInformation>
<sh:Contact>4545552073</sh:Contact>
<sh:ContactTypeIdentifier>VKN_TCKN</sh:ContactTypeIdentifier>
</sh:ContactInformation>
</sh:Receiver>
<sh:DocumentIdentification>
<sh:Standard>UBL-TR</sh:Standard>
<sh:TypeVersion>1.2</sh:TypeVersion>
<sh:InstanceIdentifier>bb583542-a81a-4b45-87d6-e90596101a41</sh:InstanceIdentifier>
<sh:Type>SENDERENVELOPE</sh:Type>
<sh:MultipleType>false</sh:MultipleType>
<sh:CreationDateAndTime>2016-01-06T16:27:25.759+02:00</sh:CreationDateAndTime>
</sh:DocumentIdentification>
</sh:StandardBusinessDocumentHeader>
<ef:Package>
<Elements>
<ElementType>INVOICE</ElementType>
<ElementCount>1</ElementCount>
<ElementList>
<ns9:Invoice>
<ext:UBLExtensions>
<ext:UBLExtension>
<ext:ExtensionContent>
...
</ext:ExtensionContent>
</ext:UBLExtension>
</ext:UBLExtensions>
<cbc:UBLVersionID>2.1</cbc:UBLVersionID>
<cbc:CustomizationID>TR1.2</cbc:CustomizationID>
<cbc:ProfileID>TICARIFATURA</cbc:ProfileID>
<cbc:ID>PAZ2015000000012</cbc:ID>
<cbc:CopyIndicator>false</cbc:CopyIndicator>
<cbc:UUID>54b0dad2-e3a7-44ee-848a-cf7977000020</cbc:UUID>
<cbc:IssueDate>2016-01-06</cbc:IssueDate>
<cbc:InvoiceTypeCode>SATIS</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>TRY</cbc:DocumentCurrencyCode>
<cbc:LineCountNumeric>0</cbc:LineCountNumeric>
<cac:Signature>
<cbc:ID schemeID="VKN_TCKN">8110120507</cbc:ID>
<cac:SignatoryParty>
<cbc:WebsiteURI>http://www.xxx.com.tr/</cbc:WebsiteURI>
<cac:PartyIdentification>
<cbc:ID schemeID="VKN">8110120507</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>xxx Kurumsal Bilgi Sistemleri A.Ş</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Besiktas Teknik Universitesi</cbc:StreetName>
<cbc:BuildingNumber>150/1G</cbc:BuildingNumber>
<cbc:CitySubdivisionName>Besıktas</cbc:CitySubdivisionName>
<cbc:CityName>Istanbul</cbc:CityName>
<cbc:PostalZone>06100</cbc:PostalZone>
<cac:Country>
<cbc:Name>Turkiye</cbc:Name>
</cac:Country>
</cac:PostalAddress>
</cac:SignatoryParty>
<cac:DigitalSignatureAttachment>
<cac:ExternalReference>
<cbc:URI>#Signature</cbc:URI>
</cac:ExternalReference>
</cac:DigitalSignatureAttachment>
</cac:Signature>
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID schemeID="VKN">7221130507</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>KAKAR KURUMSAL LTD.ŞTİ.</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:Room/>
<cbc:BuildingName/>
<cbc:BuildingNumber/>
<cbc:CitySubdivisionName>besiktas</cbc:CitySubdivisionName>
<cbc:CityName>istanbul</cbc:CityName>
<cbc:PostalZone/>
<cac:Country>
<cbc:Name>ALMANYA</cbc:Name>
</cac:Country>
</cac:PostalAddress>
<cac:Contact>
<cbc:Telephone/>
<cbc:Telefax/>
<cbc:ElectronicMail/>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:WebsiteURI/>
<cac:PartyIdentification>
<cbc:ID schemeID="VKN">2535552073</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>KAKAR LTD.ŞTİ. Test Kullanıcısı</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:ID/>
<cbc:Postbox/>
<cbc:Room/>
<cbc:StreetName/>
<cbc:BlockName/>
<cbc:BuildingName/>
<cbc:BuildingNumber/>
<cbc:CitySubdivisionName>besiktas</cbc:CitySubdivisionName>
<cbc:CityName>istanbul</cbc:CityName>
<cbc:PostalZone/>
<cbc:Region/>
<cbc:District/>
<cac:Country>
<cbc:Name>TÜRKİYE</cbc:Name>
</cac:Country>
</cac:PostalAddress>
<cac:Contact>
<cbc:Telephone/>
<cbc:Telefax/>
<cbc:ElectronicMail/>
</cac:Contact>
<cac:Person>
<cbc:FirstName/>
<cbc:FamilyName/>
</cac:Person>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="TRY">2.16</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="asdasdasdasd">0</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="TRY">2.16</cbc:TaxAmount>
<cbc:CalculationSequenceNumeric>0</cbc:CalculationSequenceNumeric>
<cbc:Percent>18</cbc:Percent>
<cac:TaxCategory>
<cac:TaxScheme>
<cbc:Name>KDV</cbc:Name>
<cbc:TaxTypeCode>0015</cbc:TaxTypeCode>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="TRY">12</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="TRY">12</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="TRY">14.16</cbc:TaxInclusiveAmount>
<cbc:AllowanceTotalAmount currencyID="TRY">0</cbc:AllowanceTotalAmount>
<cbc:PayableAmount currencyID="TRY">14.16</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="NIU">1</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="">12</cbc:LineExtensionAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:MultiplierFactorNumeric>0</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="">0</cbc:Amount>
<cbc:BaseAmount currencyID="">0</cbc:BaseAmount>
</cac:AllowanceCharge>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="">2.16</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="">0</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="">2.16</cbc:TaxAmount>
<cbc:Percent>18</cbc:Percent>
<cac:TaxCategory>
<cac:TaxScheme>
<cbc:Name>KDV</cbc:Name>
<cbc:TaxTypeCode>0015</cbc:TaxTypeCode>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:Item>
<cbc:Name>asdasd</cbc:Name>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="TRY">12</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</ns9:Invoice>
</ElementList>
</Elements>
</ef:Package>
</sh:StandardBusinessDocument>
java :
try (InputStream ubl = getClass().getResourceAsStream("/schematrons/UBL-TR_Main_Schematron.xml");) {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XmlSchemaNsUris.SCHEMATRON_NS_URI);
Schema schema = schemaFactory.newSchema(new StreamSource(ubl));
Validator validator = schema.newValidator();
validator.setErrorHandler(validationErrorHandler);
validator.validate(new StringSource(new String(binary,"UTF-8")));
} catch (Exception e) {
e.printStackTrace();
}

Related

Inlining SVG's not working on Unix Server but External SVG's ok

We are using Apache FOP to generate PDF's & have an issue with SVG's.
To include an SVG we're using something like the following...
<fo:block>
<fo:external-graphic src="classpath:image/MyImage.svg" content-width="150mm"/>
</fo:block>
The above works fine in all environments.
Now I'm trying to inline an SVG in the Stylesheet, like this...
<fo:block>
<fo:instream-foreign-object content-width="272.6mm">
<svg xmlns="http://www.w3.org/2000/svg" width="780" height="120" viewBox="0 0 780 120">
<g style="fill-opacity:0;stroke-width:2;stroke:black">
<rect x="2" y="2" width="254" height="99"/>
<rect x="256" y="2" width="485" height="99"/>
</g>
</svg>
</fo:instream-foreign-object>
</fo:block>
That works OK under Windows, but when deployed on our Linux Server, seems to do nothing.
I have read some comments on the Apache FOP Website about it using Apache Batik to render SVG's and that this requires a Graphical Environment, so will not work in many Unix configurations.
What I don't understand is, how come the external SVG is working ok on the Unix Server & inline is not?
Also, they recommend a Tool called PJA toolkit to workaround this issue, but it looks very dated, so I wonder if its going to work with our JDK 17.
I would be grateful if anyone has some Info about this.
Previously we hadn't noticed the symptom, which was a spurious empty Namespace entry on the <g> Element, meaning it no longer belonged to the SVG Namespace:
<svg xmlns="http://www.w3.org/2000/svg" height="775" viewBox="0 0 1184 775" width="1184">
<g xmlns="" style="fill-opacity:0;stroke-width:7;stroke:red">
The problem turned out to be Namespace Awareness when parsing the Stylesheet.
When enabled, the generated inline SVG works fine.
Here's a Java Source to illustrate the Solution.
(it uses Multiline Strings which require JDK >= 14)
Just look for the TODO & (un)comment that line to see the difference:
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.*;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class SvgNamespaceDomSimple {
private static final String DATA_XML = """
<?xml version="1.0" encoding="UTF-8"?><dataXml/>""";
private static final String STYLESHEET = """
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="3.0">
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="singlePage" page-width="297mm" page-height="210mm">
<fo:region-body margin-left="2.19mm" margin-top="6.75mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="singlePage">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:instream-foreign-object content-width="272.6mm" content-type="image/svg+xml">
<svg xmlns="http://www.w3.org/2000/svg" width="1184" height="775" viewBox="0 0 1184 775">
<g style="fill-opacity:0;stroke-width:7;stroke:black">
<rect width="254" height="99"/>
</g>
</svg>
</fo:instream-foreign-object>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
""";
private static Document parse(final byte[] byteArray) throws ParserConfigurationException, SAXException, IOException {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
; dbf.setNamespaceAware(true); // TODO setNamespaceAware(true)
final DocumentBuilder dbd = dbf.newDocumentBuilder();
final Document doc = dbd.parse(new ByteArrayInputStream(byteArray));
System.out.println("DocumentBuilderFactory.: " + dbf.getClass());
System.out.println("DocumentBuilder........: " + dbd.getClass());
System.out.println("Document...............: " + doc.getClass());
return doc;
}
public static void main(final String[] args) throws Exception {
System .out.println("Data XML...............:" + '\n' + DATA_XML + '\n');
System .out.println("Stylesheet.............:" + '\n' + STYLESHEET);
try(final ByteArrayInputStream ist = new ByteArrayInputStream (DATA_XML.getBytes());
final ByteArrayOutputStream ost = new ByteArrayOutputStream();)
{
final Document stylesheetDoc = parse(STYLESHEET.getBytes());
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
final Templates templates = transformerFactory.newTemplates(new DOMSource(stylesheetDoc));
final Transformer transformer = templates.newTransformer();
transformer.transform(new StreamSource(ist), new StreamResult(ost));
final String foString = new String(ost.toByteArray());
System.out.println("TransformerFactory.....: " + transformerFactory.getClass());
System.out.println("FO Bytes...............:" + '\n' + foString);
System.out.println( foString.replace(">", ">" + '\n'));
}
}
}
The resulting inline SVG then looked something like this & was rendered fine both under Windows & on our Linux Server:
<fo:instream-foreign-object content-width="272.6mm" content-type="image/svg+xml">
<svg xmlns="http://www.w3.org/2000/svg" width="1184" height="775" viewBox="0 0 1184 775">
<g style="fill-opacity:0;stroke-width:7;stroke:black">
<rect width="254" height="99"/>
</g>
</svg>
</fo:instream-foreign-object>
As a workaround, you can specify the Namespace explicitly as follows:
<fo:instream-foreign-object content-width="272.6mm" content-type="image/svg+xml">
<svg:svg xmlns:svg="http://www.w3.org/2000/svg" width="1184" height="775" viewBox="0 0 1184 775">
<svg:g style="fill-opacity:0;stroke-width:2;stroke:black">
<svg:rect width="254" height="99"/>
</svg:g>
</svg:svg>
</fo:instream-foreign-object>

Unable to run the XSLT through JAVA and Empty result observed in output

I just want to fetch a piece of tags from XML file and I'm using it XSLT.
XSLT:
<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/><xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:strip-space elements="*"/>
<xsl:template match="/testng-results">
<xsl:copy-of select="class/test-method[#status='PASS']"/>
</xsl:template></xsl:stylesheet>
Input.XML
<?xml version="1.0" encoding="UTF-8"?>
<testng-results skipped="0" failed="0" total="10" passed="10">
<class name="com.transfermoney.Transfer">
<test-method status="PASS" name="setParameter" is-config="true" duration-ms="4"
started-at="2018-08-16T21:43:38Z" finished-at="2018-08-16T21:43:38Z">
<params>
<param index="0">
<value>
<![CDATA[org.testng.TestRunner#31c2affc]]>
</value>
</param>
</params>
<reporter-output>
</reporter-output>
</test-method> <!-- setParameter -->
</class>
<class name="com.transfermoney.Transfer">
<test-method status="FAIL" name="setSettlementFlag" is-config="true" duration-ms="5"
started-at="2018-08-16T21:44:55Z" finished-at="2018-08-16T21:44:55Z">
<reporter-output>
<line>
<![CDATA[runSettlement Value Set :false]]>
</line>
</reporter-output>
</test-method> setSettlementFlag
</class>
</testng-results>
JAVA Code:
public static void main(String[] args) throws Exception {
String XML = fetchDataFrmXML(".//Test//testng-results_2.xml");
Transformer t = TransformerFactory.newInstance().newTransformer(new StreamSource(new File(".//Test//Cut.xslt")));
t.transform(new StreamSource(new StringReader(XML)), new StreamResult(new File(".//Test//Sample1.xml")));
}
Expected Output:
<test-method status="PASS" name="setParameter" is-config="true" duration-ms="4" started-at="2018-08-16T21:43:38Z" finished-at="2018-08-16T21:43:38Z">
<params>
<param index="0">
<value>
<![CDATA[runSettlement Value Set :false]]>
</value>
</param>
</params>
<reporter-output/>
</test-method>
FetchXML:
public static String fetchDataFrmXML(String fileLocation) throws Exception
{
file = new File(fileLocation);
fr = new FileReader(file);
br = new BufferedReader(fr);
String temp;
String result = "";
while ((temp = br.readLine()) != null) {
result += temp;
}
br.close();
return result;
}
I'm getting the empty sample1.xml file after I ran the JAVA class file. But if the same XSLT script I just run it through online editor it's giving an expected result.
Is there any issue in my java file to execute the XSLT? please help me on this.
Your code works for me. The only things I changed were:
declaring the variables used in your fetchDataFromXML() method
Adding the missing space after version="1.0" in your stylesheet
Changing the file names.
I added the line
System.err.println(t.getClass().getName());
to identify the XSLT engine used; the output was
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl
You might like to do the same.
Looking more carefully at the output, it displays the record with status="PASS", which is what the code is selecting, though you said you wanted the one that has status="FAIL".
A note about your fetchDataFrmXML() method: it's incredibly inefficient to build up the content of a string by repeated string concatenation this way. Use a StringBuilder instead.
(I once earned myself $10K in consultancy fees by pointing this mistake out to a client, who probably saved themselves $1m in hardware costs as a result).

How to parse unconventional XML files

I have the need to take what I consider an "unconventional" XML file that I get in and convert it into what I consider "conventional". The below XML examples have been "scrubbed" of proprietary names/values.
Here is what the "unconventional" XML file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<dataView name="document/aDocument" xmlns="http://component.mycompany.com/entity/ds" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dataItems>
<dataItem name="item1" location="item1" dataItemType="Long">
<value xsi:type="xs:string">1</value>
</dataItem>
<dataItem name="item2" location="item.seconditem(some item).ref" dataItemType="String">
<value xsi:type="xs:string">ABC2DEF3</value>
</dataItem>
</dataItems>
<dataRepeaters>
<dataRepeater name="SomeLevel1" runtimeInfomration="SomeLevel11984371030">
<dataGroups>
<dataGroup name="SomeLevel2" location="SomeLevel:(a level).thelevel" keyValue="SomeLevel119843710300" runtimeInformation="19843710300">
<dataItems>
<dataItem name="someItem1" location="someLevel.aLevel(another item)" dataItemType="String">
<value xsi:type="xs:string">12345</value>
</dataItem>
<dataItem name="someItem2" location="someLevel.aLevel(another item2)" dataItemType="Integer"/>
<dataItem name="someItem3" location="someLevel.aLevel(another item3)" dataItemType="ObjectReference">
<value xsi:type="xs:string">11:20012:3536</value>
</dataItem>
<dataItem name="someItem4" location="someLevel.aLevel(another item4)" dataItemType="String"/>
<dataItem name="someItem5" location="someLevel.aLevel(another item5)" dataItemType="String">
<value xsi:type="xs:string">someItem5 Data</value>
</dataItem>
<dataItem name="someItem6" location="someLevel.aLevel(another item6)" dataItemType="CurrencyAmount">
<value xsi:type="xs:string">123456:USD</value>
</dataItem>
</dataItems>
</dataGroup>
<dataGroup name="SomeLevel3" keyValue="SomeLevel31984371030" runtimeInformation="1984371030">
<dataRepeaters>
<dataRepeater name="SomeLevel4" runtimeInfomration="SomeLevel4">
<dataGroups>
<dataGroup name="SomeLevel5" location="anotherLevel.level5(SomeLevel5):someLevel5" keyValue="SomeLevel51984371030-11521863690" runtimeInformation="1984371030-11521863690">
<dataItems>
<dataItem name="someItem6" location="someLevel.aLevel(another item6)" dataItemType="BigDecimal">
<value xsi:type="xs:string">303.149</value>
</dataItem>
<dataItem name="someItem7" location="someLevel.aLevel(another item7)" dataItemType="CurrencyAmount">
<value xsi:type="xs:string">117:USD</value>
</dataItem>
<dataItem name="someItem8" location="someLevel.aLevel(another item8)" dataItemType="String">
<value xsi:type="xs:string">117.000000:USD</value>
</dataItem>
<dataItem name="someItem9" location="someLevel.aLevel(another item9)" dataItemType="CurrencyAmount">
<value xsi:type="xs:string">117:USD</value>
</dataItem>
</dataItems>
<dataRepeaters>
<dataRepeater name="SomeLevel6" runtimeInfomration="someLevel6">
<dataGroups/>
</dataRepeater>
</dataRepeaters>
</dataGroup>
<dataGroup name="SomeLevel7" location="anotherLevel.level5(SomeLevel7):someLevel7" keyValue="SomeLevel71984371030-11521863690" runtimeInformation="1984371030-11521863690">
<dataItems>
<dataItem name="someItem10" location="someLevel.aLevel(another item10)" dataItemType="BigDecimal">
<value xsi:type="xs:string">292.741</value>
</dataItem>
<dataItem name="someItem11" location="someLevel.aLevel(another item11)" dataItemType="CurrencyAmount">
<value xsi:type="xs:string">165:USD</value>
</dataItem>
<dataItem name="someItem12" location="someLevel.aLevel(another item12)" dataItemType="String">
<value xsi:type="xs:string">165.000000:USD</value>
</dataItem>
<dataItem name="someItem13" location="someLevel.aLevel(another item13)" dataItemType="CurrencyAmount">
<value xsi:type="xs:string">165:USD</value>
</dataItem>
</dataItems>
<dataRepeaters/>
</dataGroup>
<dataGroup name="SomeLevel8" location="anotherLevel.level5(SomeLevel8):someLevel8" keyValue="SomeLevel81984371030-11521863690" runtimeInformation="1984371030-11521863690">
<dataItems>
<dataItem name="someItem14" location="someLevel.aLevel(another item14)" dataItemType="BigDecimal">
<value xsi:type="xs:string">369.075</value>
</dataItem>
<dataItem name="someItem15" location="someLevel.aLevel(another item15)" dataItemType="CurrencyAmount">
<value xsi:type="xs:string">598:USD</value>
</dataItem>
<dataItem name="someItem16" location="someLevel.aLevel(another item16)" dataItemType="String">
<value xsi:type="xs:string">598.000000:USD</value>
</dataItem>
</dataItems>
<dataRepeaters>
<dataRepeater name="SomeLevel9" runtimeInfomration="someLevel9">
<dataGroups>
<dataGroup name="SomeLevel10" location="ownedAuto.AgreementActual(Liability).ConstantRole(Policy Form):policyForm" keyValue="aomeLevel101984371030-11521863690-115218636900" runtimeInformation="1984371030-11521863690-115218636900">
<dataItems>
<dataItem name="someItem17" location="someLevel.aLevel(another item17)" dataItemType="String">
<value xsi:type="xs:string">Some Data | ABC 123</value>
</dataItem>
<dataItem name="someItem18" location="someLevel.aLevel(another item18)" dataItemType="Integer">
<value xsi:type="xs:string">2</value>
</dataItem>
</dataItems>
</dataGroup>
</dataGroups>
</dataRepeater>
<dataRepeater name="SomeLevel10" runtimeInfomration="someLevel11">
<dataGroups/>
</dataRepeater>
</dataRepeaters>
</dataGroup>
</dataGroups>
</dataRepeater>
</dataRepeaters>
</dataGroup>
</dataGroups>
</dataRepeater>
</dataRepeaters>
</dataView>
I am trying to convert it to something like this:
<?xml version="1.0" encoding="UTF-8"?>
<dataView name="document/aDocument" xmlns="http://component.mycompany.com/entity/ds" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item1>1</item1>
<item2>ABC2DEF3</item2>
<SomeLevel1>
<SomeLevel2>
<someItem1>12345f</someItem1>
<someItem2></someItem2>
<someItem3>11:20012:3536</someItem3>
<someItem4>12345f</someItem4>
<someItem5>someItem5 Data</someItem5>
<someItem6>123456:USD</someItem6>
</SomeLevel2>
<SomeLevel3>
<SomeLevel4>
<SomeLevel5>
<someItem7>303.149</someItem7>
<someItem8>117:USD</someItem8>
<someItem9>117.000000:USD</someItem9>
<someItem10>117:USD</someItem10>
<SomeLevel6></SomeLevel6>
</SomeLevel5>
<SomeLevel7>
<someItem11>292.741</someItem11>
<someItem12>165:USD</someItem12>
<someItem13>165.000000:USD</someItem13>
<someItem14>165:USD</someItem14>
</SomeLevel7>
<SomeLevel8>
<someItem15>369.075</someItem15>
<someItem16>598:USD</someItem16>
<someItem17>598.000000:USD</someItem17>
<SomeLevel9>
<SomeLevel10>
<someItem18>Some Data | ABC 123</someItem18>
<someItem19>2</someItem19>
</SomeLevel10>
</SomeLevel9>
<SomeLevel11></SomeLevel11>
</SomeLevel8>
</SomeLevel4>
</SomeLevel3>
</SomeLevel1>
</dataView>
So basically I am trying to take the "name" attribute and make it the XML node/tag and the value between the <value> node/tag and use it as the "value" for the XML node/tag.
I have tried several different parsing/writing "routines" and the below two are the two that have gotten me the closest. So I'm leaving out the other ones as they would be just "noise".
Here is what I have tried so far:
private Document xmlDocument;
public void convertXML() {
xmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader("DSExample.xml")));
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Node dsNode = xmlDocument.getDocumentElement();
xmlDocument = docBuilder.newDocument();
// Attempt 1:
doSomethingDS(dsNode); // This will convert the XML but with NO nesting - creates example output 1
// Attempt 2:
traverseDS(dsNode); // This will create an XML with ONLY the root dataItems - Don't know why - creates example output 2
}
public void doSomethingDS(Node node) {
System.out.println(node.getNodeName());
Element xmlElement = null;
// This will be the "root" element/node "dataView":
if(node.getNodeName() != null && node.getNodeName().equalsIgnoreCase("dataView")) {
// Debugging: Print the node
printNode(node);
String nodeName = node.getNodeName().trim();
rootElement = xmlDocument.createElement(nodeName);
mPreviousElement = rootElement;
addAllAttributesToRootElement((Element) node, rootElement);
xmlDocument.appendChild(rootElement);
}
else {
// Debugging: Print the node
printNode(node);
// If has "name" property - create element/node
if(node.getAttributes() != null && node.getAttributes().getNamedItem("name") != null) {
xmlElement = createElement(xmlDocument, node);
if(xmlElement !=null && xmlDocument.getFirstChild() != null) {
xmlDocument.getFirstChild().appendChild(xmlElement);
}
}
}
NodeList nodeList = node.getChildNodes();
for(int i = 0; i < nodeList.getLength(); i++) {
Node currentNode = nodeList.item(i);
if(currentNode.getNodeType() == Node.ELEMENT_NODE) {
// recursively call this method for all the children which are of type Element
doSomethingDS(currentNode);
}
}
} // End of doSomethingDS()
public void traverseDS(Node parentNode) {
// This will create an XML with ONLY the root dataItems - Don't know why.
Element xmlElement = null;
//****************************************************************
// This will be the "root" element/node "dataView":
if(parentNode.getNodeName() != null && parentNode.getNodeName().equalsIgnoreCase("dataView")) {
// Debugging: Print the node
printNode(parentNode);
String nodeName = parentNode.getNodeName().trim();
rootElement = xmlDocument.createElement(nodeName);
mPreviousElement = rootElement;
if(!isRootNodeSet) {
mRootNode = parentNode;
isRootNodeSet = true;
}
addAllAttributesToRootElement((Element) parentNode, rootElement);
xmlDocument.appendChild(rootElement);
// traverse children
Node theNode = parentNode.getFirstChild();
if(theNode != null) {
theNode = theNode.getNextSibling();
}
else if (isRootNodeSet) {
theNode = mRootNode.getNextSibling();
}
traverseDS(theNode);
}
else {
// traverse all nodes that belong to the parent
for(Node theNode = parentNode.getFirstChild(); theNode != null; theNode = theNode.getNextSibling()) {
// Debugging: Print the node
printNode(theNode);
// If has "name" property - create element/node
if(theNode.getAttributes() != null && theNode.getAttributes().getNamedItem("name") != null) {
// Create new Element/Node
xmlElement = createElement(xmlDocument, theNode);
if(xmlElement !=null && xmlDocument.getFirstChild() != null) {
xmlDocument.getFirstChild().appendChild(xmlElement);
}
else {
System.out.println(" not a node we wanted?");
}
}
// traverse children
traverseDS(theNode);
}
}
} // End of traverseDS()
private Element createElement(Document aDoc, Node aNode) {
Element xmlElement = null;
String elementName = "";
NamedNodeMap dataNodeMap = aNode.getAttributes();
if(dataNodeMap != null && dataNodeMap.getNamedItem("name") != null) {
elementName = dataNodeMap.getNamedItem("name").getTextContent();
xmlElement = aDoc.createElement(elementName);
// if node = "dataItem" - walk node to get <value> node
// Note: some "dataItem" nodes also have a <previousValue> node - what to do with these????
if(aNode.getNodeName() != null && aNode.getNodeName().equalsIgnoreCase("dataItem")) {
// Walk Node to get <value> node
NodeList childNodes = aNode.getChildNodes();
int childNodesLength = childNodes.getLength();
for(int x = 0; x < childNodesLength; x++) {
Node childNode = childNodes.item(x);
if(childNode.getNodeName() != null && childNode.getNodeName().equalsIgnoreCase("value")) {
xmlElement.setTextContent(childNode.getTextContent());
break;
}
}
}
}
return xmlElement;
} // End of createElement()
Example Output 1 (created by doSomethingDS()):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dataView xmlns="http://component.mycompany.com/entity/ds" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="document/aDocument">
<item1>1</item1>
<item2>ABC2DEF3</item2>
<SomeLevel1/>
<SomeLevel2/>
<someItem1>12345</someItem1>
<someItem2/>
<someItem3>11:20012:3536</someItem3>
<someItem4/>
<someItem5>someItem5 Data</someItem5>
<someItem6>123456:USD</someItem6>
<SomeLevel3/>
<SomeLevel4/>
<SomeLevel5/>
<someItem6>303.149</someItem6>
<someItem7>117:USD</someItem7>
<someItem8>117.000000:USD</someItem8>
<someItem9>117:USD</someItem9>
<SomeLevel6/>
<SomeLevel7/>
<someItem10>292.741</someItem10>
<someItem11>165:USD</someItem11>
<someItem12>165.000000:USD</someItem12>
<someItem13>165:USD</someItem13>
<SomeLevel8/>
<someItem14>369.075</someItem14>
<someItem15>598:USD</someItem15>
<someItem16>598.000000:USD</someItem16>
<SomeLevel9/>
<SomeLevel10/>
<someItem17>Some Data | ABC 123</someItem17>
<someItem18>2</someItem18>
<SomeLevel11/>
</dataView>
Example Output 2 (Created by traverseDS()):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dataView xmlns="http://component.mycompany.com/entity/ds" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="document/aDocument">
<item1>1</item1>
<item2>ABC2DEF3</item2>
</dataView>
Now here is that catch.... What I get is dynamic I could get a Mac truck one time and a Toyota the next or a mixture of the two. And the size of the XML I get could be small or large. So it's hard to just use XPath or directly go after specific elements as I don't know what I'll get. This is why I'm basically walking/traversing the DOM a node at a time to extract out just what is useable.
So my question is:
What am I doing wrong in my parsing/writing of the XML file to not get it to look like what I'm trying to get it to look like?
This is (almost) trivially easy with XSLT:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ds="http://component.mycompany.com/entity/ds"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://component.mycompany.com/entity/ds"
>
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="ds:dataView" priority="1">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="ds:*[#name]">
<xsl:element name="{#name}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space()" />
</xsl:template>
</xsl:stylesheet>
applied do your input, gives you:
<dataView xmlns="http://component.mycompany.com/entity/ds" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item1>1</item1>
<item2>ABC2DEF3</item2>
<SomeLevel1>
<SomeLevel2>
<someItem1>12345</someItem1>
<someItem2 />
<someItem3>11:20012:3536</someItem3>
<someItem4 />
<someItem5>someItem5 Data</someItem5>
<someItem6>123456:USD</someItem6>
</SomeLevel2>
<SomeLevel3>
<SomeLevel4>
<SomeLevel5>
<someItem6>303.149</someItem6>
<someItem7>117:USD</someItem7>
<someItem8>117.000000:USD</someItem8>
<someItem9>117:USD</someItem9>
<SomeLevel6 />
</SomeLevel5>
<SomeLevel7>
<someItem10>292.741</someItem10>
<someItem11>165:USD</someItem11>
<someItem12>165.000000:USD</someItem12>
<someItem13>165:USD</someItem13>
</SomeLevel7>
<SomeLevel8>
<someItem14>369.075</someItem14>
<someItem15>598:USD</someItem15>
<someItem16>598.000000:USD</someItem16>
<SomeLevel9>
<SomeLevel10>
<someItem17>Some Data | ABC 123</someItem17>
<someItem18>2</someItem18>
</SomeLevel10>
</SomeLevel9>
<SomeLevel10 />
</SomeLevel8>
</SomeLevel4>
</SomeLevel3>
</SomeLevel1>
</dataView>
Notes:
Having numbered element names (someItem1 thru someItem6) will come back and bite you, eventually. XML elements have a natural order (or you can have a "number" attribute), putting a counter into the name is bad and wrong. Take my advice and don't do that (*).
To understand the solution here's a quick breakdown:
XSLT processors run XML nodes through templates by finding the best match for the XML node at hand.
The process starts with the root node.
Since there is no template explicitly matching the root node (<xsl:template match="/">), a default rule kicks in: Output nothing, but find templates for the child nodes.
The first (and only) child node is the document element (<ds:dataView>).
The template #1 matches that node, tells the processor to copy it and process its children (<xsl:apply-templates />).
Every element that has a #name is matched by template #2, which outputs an element with that name and again processes its children.
Every other element (like those <value> nodes) is - in the absence of any matching template - processed according to the mentioned default rule.
Text nodes are matched by template #3, which outputs their trimmed value.
Additional notes:
The expression in curly braces is called an attribute value template.
The template priority="1" makes sure that this template is selected for the <ds:dataView> element, because the other one would match as well.
Your result document still is in the "http://component.mycompany.com/entity/ds". This might or might not be correct. I suspect it's not correct, technically speaking, but you decide.
(*) <xsl:element name="{translate(#name, '0123456789', '')}" would be one variant to lose the counters.
XSLT has been created exactly for a task like that. As long as your Source-XML (unconventional xml) is well-formed (correct xml-syntax) so that it can be read by a standard xml-parser like DOM, you can use that.
It works like so: You create a xsl-template file that contains a declerative description how the source xml should be transformed into another format. The transformation itself is done by a XSL-Transformer.
The xsl is also an xml-format, so it should be quit easy readable, as long as the transformation is not too complex.
Here is explained how that can be implemented:
http://docs.oracle.com/javase/tutorial/jaxp/xslt/transformingXML.html

How to ignore namespaces when selecting XML nodes with XPath

I saw that there is an option to ignore namespace
xpathUtil.getObjectValue("//*[local-name() = 'object name']")
is it possible to add more objetcs names
for example
<Schema xmlns:m...... Namespace="app"
xmlns:d = ....
<complexType Name = "Comp>
<EntityType Name = "a">
<EntityType Name = "b">
</Schema>
<Schema xmlns:m...... Namespace="app2"
xmlns:d = ....
<complexType Name = "Comp2>
<EntityType Name = "a2">
<EntityType Name = "b2">
</Schema>
is it possible to get the data of the attribute EntityType only for Schema= app ? ( meaning to get the result of a and b and not a2 and b2 )
Assuming that a complete version of your input file might look like this
<?xml version="1.0" encoding="ISO-8859-1"?>
<Schemas>
<ns1:Schema xmlns:ns1="app1" >
<ns1:complexType Name = "Comp1">
<ns1:EntityType Name = "a1"/>
<ns1:EntityType Name = "b1"/>
</ns1:complexType>
</ns1:Schema>
<ns2:Schema xmlns:ns2="app2">
<ns2:complexType Name = "Comp2">
<ns2:EntityType Name = "a2"/>
<ns2:EntityType Name = "b2"/>
</ns2:complexType>
</ns2:Schema>
</Schemas>
the following XSLT shows how to filter the tags by the URI of the namespaceand the name of the namespace.
<?xml version="1.0" encoding="UTF-8"?>
<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:variable name="ns_uri1" select="'app1'"/>
<xsl:variable name="ns_uri2" select="'app2'"/>
<xsl:variable name="ns_name1" select="'ns1'"/>
<xsl:variable name="ns_name2" select="'ns2'"/>
<xsl:template match="/Schemas">
<apps>
<app1_selected_by_namespace_uri>
<xsl:copy-of select="*[local-name(.) = 'Schema' and namespace-uri(.)=$ns_uri1]"/>
</app1_selected_by_namespace_uri>
<app2_selected_by_namespace_uri>
<xsl:copy-of select="*[local-name(.) = 'Schema' and namespace-uri(.)=$ns_uri2]"/>
</app2_selected_by_namespace_uri>
<app1_selected_by_namespace_name>
<xsl:copy-of select="*[name(.) = concat($ns_name1, ':Schema')]"/>
</app1_selected_by_namespace_name>
<app2_selected_by_namespace_name>
<xsl:copy-of select="*[name(.) = concat($ns_name2, ':Schema')]"/>
</app2_selected_by_namespace_name>
</apps>
</xsl:template>
</xsl:stylesheet>
yielding the following output document
<?xml version="1.0" encoding="UTF-8"?>
<apps>
<app1_selected_by_namespace_uri>
<ns1:Schema xmlns:ns1="app1">
<ns1:complexType Name="Comp1">
<ns1:EntityType Name="a1"/>
<ns1:EntityType Name="b1"/>
</ns1:complexType>
</ns1:Schema>
</app1_selected_by_namespace_uri>
<app2_selected_by_namespace_uri>
<ns2:Schema xmlns:ns2="app2">
<ns2:complexType Name="Comp2">
<ns2:EntityType Name="a2"/>
<ns2:EntityType Name="b2"/>
</ns2:complexType>
</ns2:Schema>
</app2_selected_by_namespace_uri>
<app1_selected_by_namespace_name>
<ns1:Schema xmlns:ns1="app1">
<ns1:complexType Name="Comp1">
<ns1:EntityType Name="a1"/>
<ns1:EntityType Name="b1"/>
</ns1:complexType>
</ns1:Schema>
</app1_selected_by_namespace_name>
<app2_selected_by_namespace_name>
<ns2:Schema xmlns:ns2="app2">
<ns2:complexType Name="Comp2">
<ns2:EntityType Name="a2"/>
<ns2:EntityType Name="b2"/>
</ns2:complexType>
</ns2:Schema>
</app2_selected_by_namespace_name>
</apps>
In both cases the names are not hardcoded but given by parameters. I guess that one of the versions will suit your needs. You will find the XPath expression in the select attributes of the copy-of tags.

How to parse the below xml code?

I have sale tag as child node that exists for multiple times but in that Employee tag doesn't exists for all sale tag.need to parse this xml.Got Null pointer exception when there is no employee tag.How to parse this xml even if some child tag name doesn't exists?
<?xml version="1.0" encoding="ISO-8859-1"?>
<Transactions>
<DocumentInfo TransferType="Transactions" Copyright="2010, Hectronic GmbH" CreatedBy="HecPoll">
<CreateDate Year="2011" Month="7" Day="13"/>
<CreateTime Hour="6" Minute="0" Second="16"/>
</DocumentInfo>
<DocumentData>
<Sale RcpNum="151" Amount="228.760" Station="1" Customer="000003" Terminal="1">
<Date Year="2011" Month="07" Day="12"/>
<Time Hour="07" Minute="23" Second="00"/>
<ArticleSale Quantity="6.020" SglPriceAsSold="38.000" SglPriceAsStored="38.000" SglPrice="38.000" Amount="228.760" FCCAmount="228.760" Taxrate="18" LogicalFPNumber="1" TankNumber="3" ArtNum="3" SaleNum="1"/>
<Payment PAN="000000002117904490D" Amount="228.760" TenderCode="0" PayNum="1"/>
<Employee Lastname="V KALYANI"/>
<Vehicle LicensePlate="10K"/>
</Sale>
<Sale RcpNum="255" Amount="6650.000" Station="1" Customer="ZZZZZZ" Terminal="0">
<Date Year="2011" Month="07" Day="12"/>
<Time Hour="07" Minute="24" Second="00"/>
<ArticleSale Quantity="175.000" SglPriceAsSold="38.000" SglPriceAsStored="38.000" SglPrice="38.000" Amount="6650.000" FCCAmount="6650.000" Taxrate="19" LogicalFPNumber="1" TankNumber="1" ArtNum="3" SaleNum="1"/>
<Payment PAN="000000001885018677D" Amount="6650.000" TenderCode="0" PayNum="1"/>
</Sale>
<Sale RcpNum="152" Amount="3078.000" Station="1" Customer="000003" Terminal="1">
<Date Year="2011" Month="07" Day="12"/>
<Time Hour="07" Minute="27" Second="00"/>
<ArticleSale Quantity="81.000" SglPriceAsSold="38.000" SglPriceAsStored="38.000" SglPrice="38.000" Amount="3078.000" FCCAmount="3078.000" Taxrate="18" LogicalFPNumber="1" TankNumber="3" ArtNum="3" SaleNum="1"/>
<Payment PAN="000000002117928224D" Amount="3078.000" TenderCode="0" PayNum="1"/>
<Employee Lastname="A MUNIYANDI"/>
<Vehicle LicensePlate="10F"/>
</Sale>
</DocumentData>
</Transactions>
Thanks,
I assume you are using dom parser. If you are using getElementsByTagName() method, it will return null if no such element found. You better check for null for Employee tag.

Categories

Resources