Exemple #1
0
  /**
   * Get a Part (except a relationships part), but not its relationships part or related parts.
   * Useful if you need quick access to just this part. This can be called directly from outside the
   * library, in which case the Part will not be owned by a Package until the calling code makes it
   * so.
   *
   * @see To get a Part and all its related parts, and add all to a package, use getPart.
   * @param partByteArrays
   * @param ctm
   * @param resolvedPartUri
   * @param rel
   * @return
   * @throws Docx4JException including if result is null
   */
  public Part getRawPart(ContentTypeManager ctm, String resolvedPartUri, Relationship rel)
      throws Docx4JException {

    Part part = null;

    InputStream is = null;
    try {
      try {
        log.debug("resolved uri: " + resolvedPartUri);

        // Get a subclass of Part appropriate for this content type
        // This will throw UnrecognisedPartException in the absence of
        // specific knowledge. Hence it is important to get the is
        // first, as we do above.
        part = ctm.getPart("/" + resolvedPartUri, rel);

        log.info("ctm returned " + part.getClass().getName());

        if (part instanceof org.docx4j.openpackaging.parts.ThemePart
            || part instanceof org.docx4j.openpackaging.parts.DocPropsCorePart
            || part instanceof org.docx4j.openpackaging.parts.DocPropsCustomPart
            || part instanceof org.docx4j.openpackaging.parts.DocPropsExtendedPart
            || part instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePropertiesPart
            || part instanceof org.docx4j.openpackaging.parts.digitalsignature.XmlSignaturePart
            || part instanceof org.docx4j.openpackaging.parts.JaxbXmlPart) {

          // Nothing to do here

        } else if (part instanceof org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart) {

          log.debug("Detected BinaryPart " + part.getClass().getName());
          //					is = partStore.loadPart( resolvedPartUri);
          //					((BinaryPart)part).setBinaryData(is);

        } else if (part instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePart) {
          // ContentTypeManager initially detects them as CustomXmlDataStoragePart;
          // the below changes as necessary

          // Is it a part we know?
          is = partStore.loadPart(resolvedPartUri);
          try {
            Unmarshaller u = Context.jc.createUnmarshaller();
            Object o = u.unmarshal(is);
            log.debug(o.getClass().getName());

            PartName name = part.getPartName();
            if (o instanceof CoverPageProperties) {

              part = new DocPropsCoverPagePart(name);
              ((DocPropsCoverPagePart) part).setJaxbElement((CoverPageProperties) o);

            } else if (o instanceof org.opendope.conditions.Conditions) {

              part = new ConditionsPart(name);
              ((ConditionsPart) part).setJaxbElement((org.opendope.conditions.Conditions) o);

            } else if (o instanceof org.opendope.xpaths.Xpaths) {

              part = new XPathsPart(name);
              ((XPathsPart) part).setJaxbElement((org.opendope.xpaths.Xpaths) o);

            } else if (o instanceof org.opendope.questions.Questionnaire) {

              part = new QuestionsPart(name);
              ((QuestionsPart) part).setJaxbElement((org.opendope.questions.Questionnaire) o);

            } else if (o instanceof org.opendope.answers.Answers) {

              part = new StandardisedAnswersPart(name);
              ((StandardisedAnswersPart) part).setJaxbElement((org.opendope.answers.Answers) o);

            } else if (o instanceof org.opendope.components.Components) {

              part = new ComponentsPart(name);
              ((ComponentsPart) part).setJaxbElement((org.opendope.components.Components) o);

            } else if (o instanceof JAXBElement<?>
                && XmlUtils.unwrap(o) instanceof org.docx4j.bibliography.CTSources) {
              part = new BibliographyPart(name);
              ((BibliographyPart) part)
                  .setJaxbElement((JAXBElement<org.docx4j.bibliography.CTSources>) o);

            } else {

              log.error("TODO: handle known CustomXmlPart part  " + o.getClass().getName());

              CustomXmlDataStorage data = getCustomXmlDataStorageClass().factory();
              is.reset();
              data.setDocument(is); // Not necessarily JAXB, that's just our method name
              ((org.docx4j.openpackaging.parts.CustomXmlDataStoragePart) part).setData(data);
            }

          } catch (javax.xml.bind.UnmarshalException ue) {

            log.warn("No JAXB model for this CustomXmlDataStorage part; " + ue.getMessage());

            CustomXmlDataStorage data = getCustomXmlDataStorageClass().factory();
            is.reset();
            data.setDocument(is); // Not necessarily JAXB, that's just our method name
            ((org.docx4j.openpackaging.parts.CustomXmlDataStoragePart) part).setData(data);
          }

        } else if (part instanceof org.docx4j.openpackaging.parts.XmlPart) {

          is = partStore.loadPart(resolvedPartUri);

          //					try {
          ((XmlPart) part).setDocument(is);

          // Experimental 22/6/2011; don't fall back to binary (which we used to)

          //					} catch (Docx4JException d) {
          //						// This isn't an XML part after all,
          //						// even though ContentTypeManager detected it as such
          //						// So get it as a binary part
          //						part = getBinaryPart(partByteArrays, ctm, resolvedPartUri);
          //						log.warn("Could not parse as XML, so using BinaryPart for "
          //								+ resolvedPartUri);
          //						((BinaryPart)part).setBinaryData(is);
          //					}

        } else {
          // Shouldn't happen, since ContentTypeManagerImpl should
          // return an instance of one of the above, or throw an
          // Exception.

          log.error("No suitable part found for: " + resolvedPartUri);
          part = null;
        }

      } catch (PartUnrecognisedException e) {
        log.error("PartUnrecognisedException shouldn't happen anymore!", e);
        // Try to get it as a binary part
        part = getBinaryPart(ctm, resolvedPartUri);
        log.warn("Using BinaryPart for " + resolvedPartUri);

        //				is = partStore.loadPart( resolvedPartUri);
        //				((BinaryPart)part).setBinaryData(is);
      }
    } catch (Exception ex) {
      // IOException, URISyntaxException
      ex.printStackTrace();
      throw new Docx4JException("Failed to getPart", ex);

    } finally {
      IOUtils.closeQuietly(is);
    }

    if (part == null) {
      throw new Docx4JException(
          "cannot find part "
              + resolvedPartUri
              + " from rel "
              + rel.getId()
              + "="
              + rel.getTarget());
    }

    return part;
  }
Exemple #2
0
  /**
   * Get a Part (except a relationships part), but not its relationships part or related parts.
   * Useful if you need quick access to just this part. This can be called directly from outside the
   * library, in which case the Part will not be owned by a Package until the calling code makes it
   * so.
   *
   * @see To get a Part and all its related parts, and add all to a package, use getPart.
   * @param zf
   * @param resolvedPartUri
   * @return
   * @throws URISyntaxException
   * @throws InvalidFormatException
   */
  public static Part getRawPart(
      ZipFile zf, ContentTypeManager ctm, String resolvedPartUri, Relationship rel)
      throws Docx4JException {
    Part part = null;

    InputStream is = null;
    try {
      try {
        log.debug("resolved uri: " + resolvedPartUri);
        is = getInputStreamFromZippedPart(zf, resolvedPartUri);

        // Get a subclass of Part appropriate for this content type
        // This will throw UnrecognisedPartException in the absence of
        // specific knowledge. Hence it is important to get the is
        // first, as we do above.
        part = ctm.getPart("/" + resolvedPartUri, rel);

        if (part instanceof org.docx4j.openpackaging.parts.ThemePart) {

          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).setJAXBContext(Context.jcThemePart);
          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).unmarshal(is);

        } else if (part instanceof org.docx4j.openpackaging.parts.DocPropsCorePart) {

          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part)
              .setJAXBContext(Context.jcDocPropsCore);
          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).unmarshal(is);

        } else if (part instanceof org.docx4j.openpackaging.parts.DocPropsCustomPart) {

          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part)
              .setJAXBContext(Context.jcDocPropsCustom);
          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).unmarshal(is);

        } else if (part instanceof org.docx4j.openpackaging.parts.DocPropsExtendedPart) {

          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part)
              .setJAXBContext(Context.jcDocPropsExtended);
          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).unmarshal(is);

        } else if (part
            instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePropertiesPart) {

          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part)
              .setJAXBContext(Context.jcCustomXmlProperties);
          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).unmarshal(is);

        } else if (part
            instanceof org.docx4j.openpackaging.parts.digitalsignature.XmlSignaturePart) {

          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).setJAXBContext(Context.jcXmlDSig);
          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).unmarshal(is);

        } else if (part instanceof org.docx4j.openpackaging.parts.JaxbXmlPart) {

          // MainDocument part, Styles part, Font part etc

          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).setJAXBContext(Context.jc);
          ((org.docx4j.openpackaging.parts.JaxbXmlPart) part).unmarshal(is);

        } else if (part instanceof org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart) {

          log.debug("Detected BinaryPart " + part.getClass().getName());
          if (conserveMemory) {
            ((BinaryPart) part).setBinaryDataRef(zf.getName(), resolvedPartUri);
          } else {
            ((BinaryPart) part).setBinaryData(is);
          }

        } else if (part instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePart) {

          // Is it a part we know?
          try {
            Unmarshaller u = Context.jc.createUnmarshaller();
            Object o = u.unmarshal(is);
            log.debug(o.getClass().getName());

            PartName name = part.getPartName();

            if (o instanceof org.opendope.conditions.Conditions) {

              part = new ConditionsPart(name);
              ((ConditionsPart) part).setJaxbElement((org.opendope.conditions.Conditions) o);

            } else if (o instanceof org.opendope.xpaths.Xpaths) {

              part = new XPathsPart(name);
              ((XPathsPart) part).setJaxbElement((org.opendope.xpaths.Xpaths) o);

            } else if (o instanceof org.opendope.questions.Questionnaire) {

              part = new QuestionsPart(name);
              ((QuestionsPart) part).setJaxbElement((org.opendope.questions.Questionnaire) o);

            } else if (o instanceof org.opendope.answers.Answers) {

              part = new StandardisedAnswersPart(name);
              ((StandardisedAnswersPart) part).setJaxbElement((org.opendope.answers.Answers) o);

            } else if (o instanceof org.opendope.components.Components) {

              part = new ComponentsPart(name);
              ((ComponentsPart) part).setJaxbElement((org.opendope.components.Components) o);

            } else if (o instanceof JAXBElement<?>
                && XmlUtils.unwrap(o) instanceof org.docx4j.bibliography.CTSources) {
              part = new BibliographyPart(name);
              ((BibliographyPart) part)
                  .setJaxbElement((JAXBElement<org.docx4j.bibliography.CTSources>) o);

            } else {

              log.warn("No known part after all for CustomXmlPart " + o.getClass().getName());

              CustomXmlDataStorage data = getCustomXmlDataStorageClass().factory();
              is.reset();
              data.setDocument(is); // Not necessarily JAXB, that's just our method name
              ((org.docx4j.openpackaging.parts.CustomXmlDataStoragePart) part).setData(data);
            }

          } catch (javax.xml.bind.UnmarshalException ue) {

            // No ...
            CustomXmlDataStorage data = getCustomXmlDataStorageClass().factory();
            is.reset();
            data.setDocument(is); // Not necessarily JAXB, that's just our method name
            ((org.docx4j.openpackaging.parts.CustomXmlDataStoragePart) part).setData(data);
          }

        } else if (part instanceof org.docx4j.openpackaging.parts.XmlPart) {

          try {
            ((XmlPart) part).setDocument(is);
          } catch (Docx4JException d) {
            // This isn't an XML part after all,
            // even though ContentTypeManager detected it as such
            // So get it as a binary part
            part = getBinaryPart(zf, ctm, resolvedPartUri);
            if (conserveMemory) {
              ((BinaryPart) part).setBinaryDataRef(zf.getName(), resolvedPartUri);
            } else {
              ((BinaryPart) part).setBinaryData(is);
            }
          }

        } else {
          // Shouldn't happen, since ContentTypeManagerImpl should
          // return an instance of one of the above, or throw an
          // Exception.

          log.error("No suitable part found for: " + resolvedPartUri);
          part = null;
        }

      } catch (PartUnrecognisedException e) {
        log.warn("PartUnrecognisedException shouldn't happen anymore!");
        // Try to get it as a binary part
        part = getBinaryPart(zf, ctm, resolvedPartUri);
        if (conserveMemory) {
          ((BinaryPart) part).setBinaryDataRef(zf.getName(), resolvedPartUri);
        } else {
          ((BinaryPart) part).setBinaryData(is);
        }
      }
    } catch (Exception ex) {
      // IOException, URISyntaxException
      ex.printStackTrace();
      throw new Docx4JException("Failed to getPart", ex);

    } finally {
      if (is != null) {
        try {
          is.close();
        } catch (IOException exc) {
          exc.printStackTrace();
        }
      }
    }
    return part;
  }
  private List<Object> processRepeat(
      Object sdt, Map<String, CustomXmlPart> customXmlDataStorageParts, XPathsPart xPathsPart) {

    Tag tag = getSdtPr(sdt).getTag();

    HashMap<String, String> map = QueryString.parseQueryString(tag.getVal(), true);

    String repeatId = map.get(BINDING_ROLE_REPEAT);

    // Check, whether we are in an old repeat case. These can be removed.
    if (StringUtils.isEmpty(repeatId)) return new ArrayList<Object>();

    org.opendope.xpaths.Xpaths.Xpath xpathObj = XPathsPart.getXPathById(xPaths, repeatId);

    String storeItemId = xpathObj.getDataBinding().getStoreItemID();
    String xpath = xpathObj.getDataBinding().getXpath();
    String prefixMappings = xpathObj.getDataBinding().getPrefixMappings();

    // Get the bound XML
    String xpathBase;
    // if (xpath.endsWith("/*")) {
    // xpathBase = xpath.substring(0, xpath.length()-2);
    // } else
    if (xpath.endsWith("/")) {
      xpathBase = xpath.substring(0, xpath.length() - 1);

      // Check, whether the xpath ends with a [1]. If so, guess it comes
      // from a round-tripped path and strip it
    } else if (xpath.endsWith("[1]")) {
      xpathBase = xpath.substring(0, xpath.length() - 3);

    } else {
      xpathBase = xpath;
    }

    // DON'T Drop any trailing position! That breaks nested repeats
    // if (xpathBase.endsWith("]"))
    // xpathBase = xpathBase.substring(0, xpathBase.lastIndexOf("["));

    log.info("/n/n Repeat: using xpath: " + xpathBase);
    List<Node> repeatedSiblings =
        xpathGetNodes(customXmlDataStorageParts, storeItemId, xpathBase, prefixMappings);
    // storeItemId, xpathBase+"/*", prefixMappings);

    // Count siblings
    int numRepeats = repeatedSiblings.size();
    log.debug("yields REPEATS: " + numRepeats);

    if (numRepeats == 0) {
      // return new ArrayList<Object>(); // effectively, delete

      // Change tag to od:resultRepeatZero=id
      return repeatZero(sdt);
    }

    // duplicate content here ...
    List<Object> repeated = cloneRepeatSdt(sdt, xpathBase, numRepeats);

    // deep traverse to fix binding
    DeepTraversor dt = new DeepTraversor();
    dt.xpathBase = xpathBase;
    for (int i = 0; i < repeated.size(); i++) {

      log.info("\n Traversing clone " + i);

      dt.index = i;
      new TraversalUtil(repeated.get(i), dt);
    }
    log.info(".. deep traversals done ");

    // make bookmarks (if any) unique
    for (int i = 0; i < repeated.size(); i++) {
      try {

        // Use the sdt id for uniqueness
        long global = ((SdtElement) repeated.get(i)).getSdtPr().getId().getVal().longValue();

        BookmarkRenumber.fixRange(
            ((SdtElement) repeated.get(i)).getSdtContent().getContent(),
            "CTBookmark",
            "CTMarkupRange",
            null,
            global,
            i);
      } catch (Exception e) {
        // Shouldn't happen .. TODO remove reflection?
        log.error(e.getMessage(), e);
      }
    }

    return repeated;
  }
    @Override
    public void apply(SdtElement element, Object parent, List<Object> siblings) {

      System.out.println();

      SdtPr sdtPr = element.getSdtPr();
      if (sdtPr == null) {
        System.out.println(
            callback.indent
                + element.getClass().getSimpleName()
                + "  [no sdtPr!]"
                + " (having parent "
                + parent.getClass().getSimpleName()
                + ")");
      } else {
        System.out.println(
            callback.indent
                + element.getClass().getSimpleName()
                + " (having parent "
                + parent.getClass().getSimpleName()
                + ")");

        CTDataBinding binding = (CTDataBinding) XmlUtils.unwrap(sdtPr.getDataBinding());
        if (binding != null) {
          System.out.println(callback.indent + "  binding: " + binding.getXpath());
        }

        Tag tag = sdtPr.getTag();
        if (tag == null) return;

        System.out.println(callback.indent + "  " + tag.getVal());

        HashMap<String, String> map = QueryString.parseQueryString(tag.getVal(), true);

        String conditionId = map.get(OpenDoPEHandler.BINDING_ROLE_CONDITIONAL);
        String repeatId = map.get(OpenDoPEHandler.BINDING_ROLE_REPEAT);
        String xp = map.get(OpenDoPEHandler.BINDING_ROLE_XPATH);

        if (conditionId != null) {
          Condition c = ConditionsPart.getConditionById(conditions, conditionId);
          if (c == null) {
            System.out.println(callback.indent + "  " + "Missing condition " + conditionId);
          }

          if (c.getParticle() instanceof org.opendope.conditions.Xpathref) {
            org.opendope.conditions.Xpathref xpathRef = (Xpathref) c.getParticle();
            if (xpathRef == null) {
              System.out.println(
                  callback.indent
                      + "  "
                      + "Condition "
                      + c.getId()
                      + " references a missing xpath!");
            }

            org.opendope.xpaths.Xpaths.Xpath xpath =
                XPathsPart.getXPathById(xPaths, xpathRef.getId());
            if (xpath == null) {
              System.out.println(
                  callback.indent
                      + "  "
                      + "XPath specified in condition '"
                      + c.getId()
                      + "' is missing!");
            } else {
              System.out.println(
                  callback.indent
                      + "  "
                      + xpath.getId()
                      + ": "
                      + xpath.getDataBinding().getXpath());
            }
          } else {
            System.out.println("Complex condition: " + XmlUtils.marshaltoString(c, true, true));
          }

        } else if (repeatId != null) {

          org.opendope.xpaths.Xpaths.Xpath xpath = XPathsPart.getXPathById(xPaths, repeatId);

          if (xpath == null) {
            System.out.println(
                callback.indent
                    + "  "
                    + "XPath specified in repeat '"
                    + repeatId
                    + "' is missing!");
          } else {
            System.out.println(
                callback.indent + "  " + xpath.getId() + ": " + xpath.getDataBinding().getXpath());
          }

        } else if (xp != null) {

          org.opendope.xpaths.Xpaths.Xpath xpath = XPathsPart.getXPathById(xPaths, xp);

          if (xpath == null) {
            System.out.println(
                callback.indent + "  " + "XPath specified with id '" + xp + "' is missing!");
          } else {
            System.out.println(
                callback.indent + "  " + xpath.getId() + ": " + xpath.getDataBinding().getXpath());
          }
        }
      }
    }
  private void processDescendantBindings(Object sdt, String xpathBase, int index) {

    SdtPr sdtPr = getSdtPr(sdt);

    // log.debug(XmlUtils.marshaltoString(sdtPr, true, true));

    // Give it a unique ID (supersedes above?)
    sdtPr.setId();

    // log.debug(XmlUtils.marshaltoString(sdtPr, true, true));
    CTDataBinding binding = (CTDataBinding) XmlUtils.unwrap(sdtPr.getDataBinding());

    String thisXPath = null;

    // It'll have one of these three...
    String conditionId = null;
    String repeatId = null;
    String bindingId = null;

    org.opendope.xpaths.Xpaths.Xpath xpathObj = null;

    Tag tag = sdtPr.getTag();
    if (tag == null) return;
    HashMap<String, String> map = QueryString.parseQueryString(tag.getVal(), true);

    if (binding == null) {

      conditionId = map.get(BINDING_ROLE_CONDITIONAL);
      repeatId = map.get(BINDING_ROLE_REPEAT);

      if (conditionId != null) {

        //				c = ConditionsPart.getConditionById(conditions, conditionId);
        //				if (c == null) {
        //					log.error("Missing condition " + conditionId);
        //					throw new InputIntegrityException("Required condition '" + conditionId + "' is
        // missing");
        //				}
        //
        //				// TODO: this code assumes the condition contains
        //				// a simple xpath
        //				log.debug("Using condition"
        //						+ XmlUtils.marshaltoString(c, true, true));
        //				xpathObj = getXPathFromCondition(c);
        //				thisXPath = xpathObj.getDataBinding().getXpath();

        processDescendantCondition(sdt, xpathBase, index, tag);
        return;

      } else if (repeatId != null) {

        xpathObj = XPathsPart.getXPathById(xPaths, repeatId);
        thisXPath = xpathObj.getDataBinding().getXpath();

      } else if (map.containsKey(BINDING_CONTENTTYPE)
          || map.containsKey(BINDING_HANDLER)
          || map.containsKey(BINDING_PROGID)) {

        xpathObj = XPathsPart.getXPathById(xPaths, map.get(BINDING_ROLE_XPATH));
        thisXPath = xpathObj.getDataBinding().getXpath();

      } else {

        log.warn("couldn't find binding or bindingrole!");
        // not all sdt's need have a binding;
        // they could be present in the docx for other purposes
        return;

        // NB an OpenDoPE xpath tag (with no w:binding element)
        // eg as created by authoring tool for a "count(" XPath
        // ends up here.
      }

    } else {
      thisXPath = binding.getXpath();

      // Set this stuff up now
      bindingId = map.get(BINDING_ROLE_XPATH);
      xpathObj = XPathsPart.getXPathById(xPaths, bindingId);

      // Sanity test
      if (!thisXPath.equals(xpathObj.getDataBinding().getXpath())) {
        log.error(
            "XPaths didn't match for id "
                + bindingId
                + ": \n\r    "
                + thisXPath
                + "\n\rcf. "
                + xpathObj.getDataBinding().getXpath());
      }

      // 2012 09 20 - when did this break?
      // thisXPath = xpathObj.getDataBinding().getXpath();
    }

    //		System.out.println("xpathBase: " + xpathBase);
    //		System.out.println("index: " + index);
    //		System.out.println("thisXPath: " + thisXPath);

    final String newPath = enhanceXPath(xpathBase, index + 1, thisXPath);

    //		System.out.println("newPath: " + newPath);

    if (log.isDebugEnabled() && !thisXPath.equals(newPath)) {
      log.debug("xpath prefix enhanced " + thisXPath + " to " + newPath);
    }

    if (binding == null) {

      if (repeatId != null) {

        // Create the new xpath object
        org.opendope.xpaths.Xpaths.Xpath newXPathObj =
            createNewXPathObject(newPath, xpathObj, index);

        // set sdt to use it
        map.put(BINDING_ROLE_REPEAT, newXPathObj.getId());
        tag.setVal(QueryString.create(map));

      } else if (map.containsKey(BINDING_CONTENTTYPE)
          || map.containsKey(BINDING_HANDLER)
          || map.containsKey(BINDING_PROGID)) {

        // Also need to create new xpath id, and add that
        org.opendope.xpaths.Xpaths.Xpath newXPathObj =
            createNewXPathObject(newPath, xpathObj, index);

        // set sdt to use it
        map.put(BINDING_ROLE_XPATH, newXPathObj.getId());
        tag.setVal(QueryString.create(map));
      }

    } else {
      binding.setXpath(newPath);

      // Also need to create new xpath id, and add that
      org.opendope.xpaths.Xpaths.Xpath newXPathObj = createNewXPathObject(newPath, xpathObj, index);

      // set sdt to use it
      map.put(BINDING_ROLE_XPATH, newXPathObj.getId());
      tag.setVal(QueryString.create(map));
    }
  }