/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is part of dcm4che, an implementation of DICOM(TM) in
* Java(TM), hosted at https://github.com/gunterze/dcm4che.
*
* The Initial Developer of the Original Code is
* Agfa Healthcare.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* See @authors listed below
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.dcm4che3.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.BulkData;
import org.dcm4che3.data.Fragments;
import org.dcm4che3.data.Tag;
import org.dcm4che3.data.UID;
import org.dcm4che3.data.VR;
import org.junit.Assert;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Tests for {@link SAXReader} and {@link SAXWriter}.
*
* @author Hermann Czedik-Eysenberg <hermann-agfa@czedik.net>
*/
public class XMLTest {
private static final String REFERENCE_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><NativeDicomModel xml:space=\"preserve\"><DicomAttribute keyword=\"SpecificCharacterSet\" tag=\"00080005\" vr=\"CS\"><Value number=\"1\">ISO 2022 IR 87</Value></DicomAttribute><DicomAttribute keyword=\"ImageType\" tag=\"00080008\" vr=\"CS\"><Value number=\"1\">DERIVED</Value><Value number=\"2\"/><Value number=\"3\">PRIMARY</Value><Value number=\"4\"/><Value number=\"5\">TEST</Value></DicomAttribute><DicomAttribute keyword=\"AccessionNumber\" tag=\"00080050\" vr=\"SH\"/><DicomAttribute keyword=\"SourceImageSequence\" tag=\"00082112\" vr=\"SQ\"><Item number=\"1\"><DicomAttribute keyword=\"ReferencedSOPClassUID\" tag=\"00081150\" vr=\"UI\"><Value number=\"1\">1.2.840.10008.5.1.4.1.1.2</Value></DicomAttribute><DicomAttribute keyword=\"ReferencedSOPInstanceUID\" tag=\"00081155\" vr=\"UI\"><Value number=\"1\">1.2.3.4</Value></DicomAttribute></Item></DicomAttribute><DicomAttribute tag=\"00090002\" privateCreator=\"PRIVATE\" vr=\"OB\"><InlineBinary>AAE=</InlineBinary></DicomAttribute><DicomAttribute keyword=\"PatientName\" tag=\"00100010\" vr=\"PN\"><PersonName number=\"1\"><Alphabetic><FamilyName>af</FamilyName><GivenName>ag</GivenName></Alphabetic><Ideographic><FamilyName>if</FamilyName><GivenName>ig</GivenName></Ideographic><Phonetic><FamilyName>pf</FamilyName><GivenName>pg</GivenName></Phonetic></PersonName></DicomAttribute><DicomAttribute keyword=\"FrameTime\" tag=\"00181063\" vr=\"DS\"><Value number=\"1\">33</Value></DicomAttribute><DicomAttribute keyword=\"SamplesPerPixel\" tag=\"00280002\" vr=\"US\"><Value number=\"1\">1</Value></DicomAttribute><DicomAttribute keyword=\"NumberOfFrames\" tag=\"00280008\" vr=\"IS\"><Value number=\"1\">1</Value></DicomAttribute><DicomAttribute keyword=\"FrameIncrementPointer\" tag=\"00280009\" vr=\"AT\"><Value number=\"1\">00181063</Value></DicomAttribute><DicomAttribute keyword=\"OverlayData\" tag=\"60003000\" vr=\"OW\"><BulkData uuid=\"someuuid\"/></DicomAttribute><DicomAttribute keyword=\"PixelData\" tag=\"7FE00010\" vr=\"OB\"><BulkData uri=\"file:/PixelData?offsets=0,1234&lengths=0,5678\"/></DicomAttribute></NativeDicomModel>";
@Test
public void testDcm2Xml() throws Exception {
Attributes dataset = createTestDataset();
String xml = dcm2xml(dataset);
Assert.assertEquals(REFERENCE_XML, xml);
}
private String dcm2xml(Attributes dataset) throws TransformerFactoryConfigurationError, TransformerConfigurationException, SAXException, UnsupportedEncodingException {
SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory.newInstance();
ByteArrayOutputStream xmlOutput = new ByteArrayOutputStream();
TransformerHandler handler = tf.newTransformerHandler();
//handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
//handler.getTransformer().setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
handler.setResult(new StreamResult(xmlOutput));
SAXWriter writer = new SAXWriter(handler);
writer.write(dataset);
return xmlOutput.toString(StandardCharsets.UTF_8.name());
}
private Attributes createTestDataset() {
Attributes dataset = new Attributes();
dataset.setString(Tag.SpecificCharacterSet, VR.CS, "ISO 2022 IR 87");
dataset.setString(Tag.ImageType, VR.CS, "DERIVED", null, "PRIMARY", "", "TEST");
dataset.setNull(Tag.AccessionNumber, VR.SH);
Attributes item = new Attributes(2);
dataset.newSequence(Tag.SourceImageSequence, 1).add(item);
item.setString(Tag.ReferencedSOPClassUID, VR.UI, UID.CTImageStorage);
item.setString(Tag.ReferencedSOPInstanceUID, VR.UI, "1.2.3.4");
dataset.setString(Tag.PatientName, VR.PN, "af^ag=if^ig=pf^pg");
dataset.setBytes("PRIVATE", 0x00090002, VR.OB, new byte[] { 0, 1 });
dataset.setDouble(Tag.FrameTime, VR.DS, 33.0);
dataset.setInt(Tag.SamplesPerPixel, VR.US, 1);
dataset.setInt(Tag.NumberOfFrames, VR.IS, 1);
dataset.setInt(Tag.FrameIncrementPointer, VR.AT, Tag.FrameTime);
dataset.setValue(Tag.OverlayData, VR.OW, new BulkData("someuuid", null, false));
Fragments frags = dataset.newFragments(Tag.PixelData, VR.OB, 2);
frags.add(null);
frags.add(new BulkData(null, "file:/PixelData?offset=1234&length=5678", false));
return dataset;
}
@Test
public void testXml2Dcm() throws Exception {
Attributes dataset = xml2dcm(REFERENCE_XML);
Attributes referenceDataset = createTestDataset();
// the null value will be an empty string after converting to XML, therefore we have to adapt the reference
referenceDataset.setString(Tag.ImageType, VR.CS, "DERIVED", "", "PRIMARY", "", "TEST");
Assert.assertEquals(referenceDataset, dataset);
}
private Attributes xml2dcm(String xml) throws ParserConfigurationException, SAXException, IOException {
Attributes dataset = new Attributes();
ContentHandlerAdapter ch = new ContentHandlerAdapter(dataset);
SAXParserFactory f = SAXParserFactory.newInstance();
SAXParser p = f.newSAXParser();
p.parse(new InputSource(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))), ch);
return dataset;
}
}