getting 'ERROR: 'Syntax error in '. castable as xs:integer' while Trying to transform xml, based on Data type of value the tag is containing

Viewed 57

here is my _ignoreText.xsl file

<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="no" />
        <xsl:template match="*|@*|text()|comment()|processing-instruction()" >
    
            <xsl:if test="normalize-space(.) != '' or ./@* != ''">
                <xsl:copy>
                    <xsl:apply-templates select="*|@*|text()|comment()|processing-instruction()"/>
                </xsl:copy>
            </xsl:if>
    
            <xsl:variable name="type">
                <xsl:choose>
                    <xsl:when test=". castable as xs:integer">
                        <xsl:text>Integer</xsl:text>
                    </xsl:when>
                    <xsl:when test=". castable as xs:boolean">
                        <xsl:text>Boolean</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text>String</xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
    
    
        </xsl:template>
    
    </xsl:stylesheet>

below is a java code in which i am using above _ignoreText.xsl file to transform xml

import org.custommonkey.xmlunit.Transform;
import java.io.File;


public class TransformDemo1 {
    public static void main(String args[]) throws Exception {

        String xsltfilename="D:\\Demo\\src\\test\\java\\StringXml\\_ignoreText.xsl";
        File xsltfile=new File(xsltfilename);

        String strSource = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
                "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\">\n" +
                "    <SOAP-ENV:Body>\n" +
                "        <return>\n" +
                "            <ICD10Flag>hello</ICD10Flag>\n" +
                "            <status>success</status>\n" +
                "        </return>\n" +
                "    </SOAP-ENV:Body>\n" +
                "</SOAP-ENV:Envelope>\n";
        Transform docSource = new Transform(strSource, xsltfile);

    }
}

following is the Error i am getting.

ERROR:  'Syntax error in '. castable as xs:integer'.'
FATAL ERROR:  'file:/D:/Demo/src/test/java/StringXml/_ignoreText.xsl: line 18: Required attribute 'test' is missing.'
Exception in thread "main" org.custommonkey.xmlunit.exceptions.ConfigurationException: file:/D:/RijvanPactPOC/2/DemoProjectPactConsumer/src/test/java/StringXml/_ignoreText.xsl: line 18: Required attribute 'test' is missing.
    at org.custommonkey.xmlunit.Transform.getTransformer(Transform.java:201)
    at org.custommonkey.xmlunit.Transform.<init>(Transform.java:161)
    at org.custommonkey.xmlunit.Transform.<init>(Transform.java:92)
    at StringXml.TransformDemo1.main(TransformDemo1.java:31)
Caused by: javax.xml.transform.TransformerConfigurationException: file:/D:/Demo/src/test/java/StringXml/_ignoreText.xsl: line 18: Required attribute 'test' is missing.
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:1061)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:817)
    at org.custommonkey.xmlunit.Transform.getTransformer(Transform.java:196)
    ... 3 more

Process finished with exit code 1

please suggest any solution or any other Library using that i can Transform the XML based the data type of the value the xml tag is containing

Ex. 1

<status>success</status>

should be transformed to

<status>String</status>

Ex. 2

<status>123</status>

should be transformed to

<status>Integer</status>
1 Answers

Looks like you are trying to match the XML with node content's data type.

If that is the case you can use the custom DifferenceEvaluator as below.

public class XMLUnitDiffDemo{

public static void main(String args[]) throws Exception {
  String strSource = "<root><test>true</test>" +
                "<test2>2</test2>" +
                "<test1>1</test1>" +
                "</root>";
  String strTest = "<root><test>true</test>" +
                "<test1>1</test1>" +
                "<test2>2</test2>" +
                "</root>";


 Diff myDiff = DiffBuilder.compare(xmlSource).withTest(xmlCompareWith)
                .ignoreComments()
                .ignoreWhitespace()
                .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName))
                .withDifferenceEvaluator(new DataTypeElementDifferenceEvaluator())
                .checkForSimilar().build();

System.out.println(!myDiff.hasDifferences())
}
}

Custom implementation.


class DataTypeElementDifferenceEvaluator implements DifferenceEvaluator {

    @Override
    public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) {
        if (outcome == ComparisonResult.EQUAL) return outcome; // only evaluate differences.
        Node controlNode = comparison.getControlDetails().getTarget();
        Node testNode = comparison.getTestDetails().getTarget();
        String controlnodename = controlNode.getNodeName();
        String testNodename = testNode.getNodeName();
        String conCN = controlNode.getTextContent();
        String conTN = testNode.getTextContent();
        if(controlnodename.equalsIgnoreCase(testNodename)){
            System.out.println(getDataType(conCN) + " ==  " + getDataType(conTN));
            if(getDataType(conCN).equalsIgnoreCase(getDataType(conTN))) {
                return ComparisonResult.SIMILAR;
            }
        }
        return outcome;
    }

public static String getDataType(String input) {

        String dataType = null;
        // checking for Integer
        if (input.matches("\\d+")) {
            dataType = "java.lang.Integer";
        }
        // checking for floating point numbers
        else if (input.matches("\\d*[.]\\d+")) {
            dataType = "java.lang.Double";
        }
        // checking for date format dd/mm/yyyy
        else if (input.matches(
                "\\d{2}[/]\\d{2}[/]\\d{4}")) {
            dataType = "java.util.Date";
        }
        // checking for date format mm/dd/yyyy
        else if (input.matches(
                "\\d{2}[/]\\d{2}[/]\\d{4}")) {
            dataType = "java.util.Date";
        }
        // checking for date format dd-mon-yy
        else if (input.matches(
                "\\d{2}[-]\\w{3}[-]\\d{2}")) {
            dataType = "java.util.Date";
        }
        // checking for date format dd-mon-yyyy
        else if (input.matches(
                "\\d{2}[-]\\w{3}[-]\\d{4}")) {
            dataType = "java.util.Date";
        }
        // checking for date format dd-month-yy
        else if (input.matches("\\d{2}[-]\\w+[-]\\d{2}")) {
            dataType = "java.util.Date";
        }
        // checking for date format dd-month-yyyy
        else if (input.matches("\\d{2}[-]\\w+[-]\\d{4}")) {
            dataType = "java.util.Date";
        }
        // checking for date format yyyy-mm-dd
        else if (input.matches(
                "\\d{4}[-]\\d{2}[-]\\d{2}")) {
            dataType = "java.util.Date";
        }
        // checking for String
        else {
            dataType = "java.lang.String";
        }

        return dataType;

    }

}



Related