/**
  * Read a DICOM dataset and write an XML representation of it to the standard output, or vice
  * versa.
  *
  * @param arg either one filename of the file containing the DICOM dataset, or a direction
  *     argument (toDICOM or toXML, case insensitive) and an input filename
  */
 public static void main(String arg[]) {
   try {
     boolean bad = true;
     boolean toXML = true;
     String filename = null;
     if (arg.length == 1) {
       bad = false;
       toXML = true;
       filename = arg[0];
     } else if (arg.length == 2) {
       filename = arg[1];
       if (arg[0].toLowerCase(java.util.Locale.US).equals("toxml")) {
         bad = false;
         toXML = true;
       } else if (arg[0].toLowerCase(java.util.Locale.US).equals("todicom")
           || arg[0].toLowerCase(java.util.Locale.US).equals("todcm")) {
         bad = false;
         toXML = false;
       }
     }
     if (bad) {
       System.err.println(
           "usage: XMLRepresentationOfDicomObjectFactory [toDICOM|toXML] inputfile");
     } else {
       if (toXML) {
         AttributeList list = new AttributeList();
         // System.err.println("reading list");
         list.read(filename, null, true, true);
         // System.err.println("making document");
         Document document = new XMLRepresentationOfDicomObjectFactory().getDocument(list);
         // System.err.println(toString(document));
         write(System.out, document);
       } else {
         // long startReadTime = System.currentTimeMillis();
         AttributeList list =
             new XMLRepresentationOfDicomObjectFactory().getAttributeList(filename);
         // System.err.println("AttributeList.main(): read XML and create DICOM AttributeList -
         // done in "+(System.currentTimeMillis()-startReadTime)+" ms");
         String sourceApplicationEntityTitle =
             Attribute.getSingleStringValueOrEmptyString(
                 list, TagFromName.SourceApplicationEntityTitle);
         list.removeMetaInformationHeaderAttributes();
         FileMetaInformation.addFileMetaInformation(
             list, TransferSyntax.ExplicitVRLittleEndian, sourceApplicationEntityTitle);
         list.write(
             System.out,
             TransferSyntax.ExplicitVRLittleEndian,
             true /*useMeta*/,
             true /*useBufferedStream*/);
       }
     }
   } catch (Exception e) {
     e.printStackTrace(System.err);
   }
 }
  /**
   * @param list
   * @param document
   * @param parent
   */
  void addAttributesFromListToNode(AttributeList list, Document document, Node parent) {
    DicomDictionary dictionary = list.getDictionary();
    Iterator i = list.values().iterator();
    while (i.hasNext()) {
      Attribute attribute = (Attribute) i.next();
      AttributeTag tag = attribute.getTag();

      String elementName = dictionary.getNameFromTag(tag);
      if (elementName == null) {
        elementName = makeElementNameFromHexadecimalGroupElementValues(tag);
      }
      Node node = document.createElement(elementName);
      parent.appendChild(node);

      {
        Attr attr = document.createAttribute("group");
        attr.setValue(HexDump.shortToPaddedHexString(tag.getGroup()));
        node.getAttributes().setNamedItem(attr);
      }
      {
        Attr attr = document.createAttribute("element");
        attr.setValue(HexDump.shortToPaddedHexString(tag.getElement()));
        node.getAttributes().setNamedItem(attr);
      }
      {
        Attr attr = document.createAttribute("vr");
        attr.setValue(ValueRepresentation.getAsString(attribute.getVR()));
        node.getAttributes().setNamedItem(attr);
      }

      if (attribute instanceof SequenceAttribute) {
        int count = 0;
        Iterator si = ((SequenceAttribute) attribute).iterator();
        while (si.hasNext()) {
          SequenceItem item = (SequenceItem) si.next();
          Node itemNode = document.createElement("Item");
          Attr numberAttr = document.createAttribute("number");
          numberAttr.setValue(Integer.toString(++count));
          itemNode.getAttributes().setNamedItem(numberAttr);
          node.appendChild(itemNode);
          addAttributesFromListToNode(item.getAttributeList(), document, itemNode);
        }
      } else {
        // Attr attr = document.createAttribute("value");
        // attr.setValue(attribute.getDelimitedStringValuesOrEmptyString());
        // node.getAttributes().setNamedItem(attr);

        // node.appendChild(document.createTextNode(attribute.getDelimitedStringValuesOrEmptyString()));

        String values[] = null;
        try {
          values = attribute.getStringValues();
        } catch (DicomException e) {
          // e.printStackTrace(System.err);
        }
        if (values != null) {
          for (int j = 0; j < values.length; ++j) {
            Node valueNode = document.createElement("value");
            Attr numberAttr = document.createAttribute("number");
            numberAttr.setValue(Integer.toString(j + 1));
            valueNode.getAttributes().setNamedItem(numberAttr);
            valueNode.appendChild(document.createTextNode(values[j]));
            node.appendChild(valueNode);
          }
        }
      }
    }
  }
 /**
  * @param list
  * @param parent
  * @exception NumberFormatException
  * @exception DicomException
  */
 void addAttributesFromNodeToList(AttributeList list, Node parent)
     throws NumberFormatException, DicomException {
   if (parent != null) {
     Node node = parent.getFirstChild();
     while (node != null) {
       String elementName = node.getNodeName();
       NamedNodeMap attributes = node.getAttributes();
       if (attributes != null) {
         Node vrNode = attributes.getNamedItem("vr");
         Node groupNode = attributes.getNamedItem("group");
         Node elementNode = attributes.getNamedItem("element");
         if (vrNode != null && groupNode != null && elementNode != null) {
           String vrString = vrNode.getNodeValue();
           String groupString = groupNode.getNodeValue();
           String elementString = elementNode.getNodeValue();
           if (vrString != null && groupString != null && elementString != null) {
             byte[] vr = vrString.getBytes();
             int group = Integer.parseInt(groupString, 16);
             int element = Integer.parseInt(elementString, 16);
             AttributeTag tag = new AttributeTag(group, element);
             if ((group % 2 == 0 && element == 0)
                 || (group == 0x0008 && element == 0x0001)
                 || (group == 0xfffc && element == 0xfffc)) {
               // System.err.println("ignoring group length or length to end or dataset trailing
               // padding "+tag);
             } else {
               if (vrString.equals("SQ")) {
                 SequenceAttribute a = new SequenceAttribute(tag);
                 // System.err.println("Created "+a);
                 if (node.hasChildNodes()) {
                   Node childNode = node.getFirstChild();
                   while (childNode != null) {
                     String childNodeName = childNode.getNodeName();
                     // System.err.println("childNodeName = "+childNodeName);
                     if (childNodeName != null && childNodeName.equals("Item")) {
                       // should check item number, but ignore for now :(
                       // System.err.println("Adding item to sequence");
                       AttributeList itemList = new AttributeList();
                       addAttributesFromNodeToList(itemList, childNode);
                       a.addItem(itemList);
                     }
                     // else may be a #text element in between
                     childNode = childNode.getNextSibling();
                   }
                 }
                 // System.err.println("Sequence Attribute is "+a);
                 list.put(tag, a);
               } else {
                 Attribute a = AttributeFactory.newAttribute(tag, vr);
                 // System.err.println("Created "+a);
                 if (node.hasChildNodes()) {
                   Node childNode = node.getFirstChild();
                   while (childNode != null) {
                     String childNodeName = childNode.getNodeName();
                     // System.err.println("childNodeName = "+childNodeName);
                     if (childNodeName != null && childNodeName.equals("value")) {
                       // should check value number, but ignore for now :(
                       String value = childNode.getTextContent();
                       // System.err.println("Value value = "+value);
                       if (value != null) {
                         value =
                             StringUtilities.removeLeadingOrTrailingWhitespaceOrISOControl(
                                 value); // just in case
                         a.addValue(value);
                       }
                     }
                     // else may be a #text element in between
                     childNode = childNode.getNextSibling();
                   }
                 }
                 // System.err.println("Attribute is "+a);
                 list.put(tag, a);
               }
             }
           }
         }
       }
       node = node.getNextSibling();
     }
   }
 }