0

I am using Java 8 with XSLT 1.0.

I have the below xml file used as input to XSLT

<?xml version="1.0" encoding="UTF-8"?>
<Research xmlns="http://www.rixml.org/2013/2/RIXML">
    <Product>
        <StatusInfo statusType="Revised"/>
    </Product>
</Research>

I am trying to update the statusType attribute to Deleted from the current value and below is the xslt doing the same.

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template>

<xsl:template match="//Research/Product/StatusInfo">
    <xsl:element name="StatusInfo">
        <xsl:attribute name="stausType">Deleted</xsl:attribute>
    </xsl:element>
</xsl:template>

But when I try to apply xslt using below Java program it is not giving any error but it is failing to update the statusType in newly generated xml.

As soon as I removed the xmlns attribute of Research element and apply the same xslt it is updating the attribute properly.

I am using below Java program to apply xslt on the input file to generate the final output file.

public class TestPullbackRIXMLXSLT1 {

private static final String SOURCE_XSLT_PATH="C:\\MDERedesignPoc\\distribution-engine-publications\\package\\config\\xslt\\RIXMLPullback.xsl";
private static final String INPUT_XML_FILE_PATH="C:\\export\\rschapps\\rschdistengine\\workarea-qa\\2002434_1_10893_DISTRIBUTE\\core\\input.xml";
private static final String OUTPUT_XML_FILE_PATH="C:\\export\\rschapps\\rschdistengine\\workarea-qa\\2002434_1_10893_DISTRIBUTE\\core\\output.xml";
private static final Logger logger = LoggerFactory.getLogger(TestRIXMLXSLT.class);

public static void main(String[] args) {

    try
    {

        System.out.println("Creation of RIXML 24 ");
        Transformer transformer = createTransformer();
        StreamSource source = new StreamSource(new File(INPUT_XML_FILE_PATH));
        File outputXML=new File(OUTPUT_XML_FILE_PATH);
        StreamResult result = new StreamResult(outputXML);
        transformer.transform(source, result);

    }
    catch(Exception e) {
        e.printStackTrace();
    }

}
private static Transformer createTransformer() throws TransformerConfigurationException{
    TransformerFactory factory = TransformerFactory.newInstance();
    factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "all");
    factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "all");
    Templates cachedXSLT = factory.newTemplates(new StreamSource(new File(SOURCE_XSLT_PATH)));
    Transformer transformer = cachedXSLT.newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.INDENT, Constants.YES);
    transformer.setOutputProperty(Constants.TRANSFORMER_INDENT_PARAMETER_NAME, Constants.TRANSFORMER_INDENT_PARAMETER_VALUE);
    return transformer;
}

}

I am not able to understand why xmlns is causing the issue while applying the xslt and if attribute is not present everything is working fine.

I have to keep the xmlns (namespace) attribute in input.xml to avoid failures.

Can anybody please help me fix this issue?

1 Answers1

0

This question kind of questions comes back very often. You need to take into account the namespace. Do some reading on namespaces.

It can be done like 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"
    xmlns:ri="http://www.rixml.org/2013/2/RIXML"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//ri:Research/ri:Product/ri:StatusInfo">
    <xsl:element name="StatusInfo" namespace="http://www.rixml.org/2013/2/RIXML">
        <xsl:attribute name="statusType">Deleted</xsl:attribute>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

See it working here: https://xsltfiddle.liberty-development.net/ehVZvw8

Or you could simplify it to 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"
    xmlns:ri="http://www.rixml.org/2013/2/RIXML"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ri:StatusInfo/@statusType">
    <xsl:attribute name="statusType">Deleted</xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

See it working here: https://xsltfiddle.liberty-development.net/ehVZvw8/1

Sebastien
  • 2,672
  • 1
  • 8
  • 13
  • @Sebastian Thanks for resolving my issue . I will definately look more in name spaces. I just want to confirm one more stuff regrading xsl:copy tag does it copy any of the CDATA sections if they are present in the source xml when it copies the source xml nodes to result xml.If not is there any way to do that ? – user2709315 May 19 '20 at 14:03