You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hop.apache.org by ha...@apache.org on 2021/12/14 21:21:50 UTC

[incubator-hop] branch master updated: HOP-3494 : add "get fields from snippet" for xml input

This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-hop.git


The following commit(s) were added to refs/heads/master by this push:
     new 506d7bb  HOP-3494 : add "get fields from snippet" for xml input
     new 390b82e  Merge pull request #1217 from uraychang/xmlsnippet
506d7bb is described below

commit 506d7bb333d6e194f5c88325a1628558f1e33717
Author: ray.chang <ur...@gmail.com>
AuthorDate: Fri Dec 10 14:40:40 2021 +0800

    HOP-3494 : add "get fields from snippet" for xml input
---
 .../xml/getxmldata/GetXmlDataDialog.java           | 201 ++++++++++++++-------
 .../getxmldata/LoopNodesImportProgressDialog.java  |  45 +++--
 .../transforms/xml/getxmldata/PdOption.java        |  82 +++++++++
 .../XmlInputFieldsImportProgressDialog.java        |  45 ++---
 .../getxmldata/messages/messages_en_US.properties  |   3 +
 .../apache/hop/ui/core/dialog/EnterTextDialog.java |  35 +++-
 6 files changed, 296 insertions(+), 115 deletions(-)

diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java
index 80b1641..26a2887 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/GetXmlDataDialog.java
@@ -110,7 +110,7 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
   private Label wlLimit;
   private Text wLimit;
 
-  private TextVar wLoopXPath;
+  private TextVar wLoopXPath, wLoopXPathSnippet;
 
   private Label wlPrunePath;
   private TextVar wPrunePath;
@@ -157,6 +157,12 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
 
   String precNodeName = null;
 
+  private PdOption readFilePdOption;
+  private PdOption readUrlPdOption;
+  private PdOption readXmlPdOption;
+  private PdOption readHopVfsPdOption;
+  private PdOption readSnippetPdOption;
+
   public GetXmlDataDialog(
       Shell parent, IVariables variables, Object in, PipelineMeta pipelineMeta, String sname) {
     super(parent, variables, (BaseTransformMeta) in, pipelineMeta, sname);
@@ -579,16 +585,7 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
     XmlConfgroupLayout.marginHeight = 10;
     wXmlConf.setLayout(XmlConfgroupLayout);
 
-    Button wbbLoopPathList = new Button(wXmlConf, SWT.PUSH | SWT.CENTER);
-    props.setLook(wbbLoopPathList);
-    wbbLoopPathList.setText(BaseMessages.getString(PKG, "GetXMLDataDialog.LoopPathList.Button"));
-    wbbLoopPathList.setToolTipText(
-        BaseMessages.getString(PKG, "System.Tooltip.BrowseForFileOrDirAndAdd"));
-    FormData fdbLoopPathList = new FormData();
-    fdbLoopPathList.right = new FormAttachment(100, 0);
-    fdbLoopPathList.top = new FormAttachment(0, 0);
-    wbbLoopPathList.setLayoutData(fdbLoopPathList);
-
+    Button wbbLoopPathList = getWbbLoopPathList(wXmlConf);
     wbbLoopPathList.addSelectionListener(
         new SelectionAdapter() {
           @Override
@@ -965,10 +962,12 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
 
     wGet = new Button(wFieldsComp, SWT.PUSH);
     wGet.setText(BaseMessages.getString(PKG, "GetXMLDataDialog.GetFields.Button"));
-    fdGet = new FormData();
-    fdGet.left = new FormAttachment(50, 0);
-    fdGet.bottom = new FormAttachment(100, 0);
-    wGet.setLayoutData(fdGet);
+
+    Button wGetSnippet = new Button(wFieldsComp, SWT.PUSH);
+    wGetSnippet.setText(BaseMessages.getString(PKG, "GetXMLDataDialog.Button.SelectFieldsSnippet"));
+    wGetSnippet.addListener(SWT.Selection, e -> getFromSnippet());
+
+    setButtonPositions(new Button[]{wGet, wGetSnippet}, margin, null);
 
     final int FieldsRows = input.getInputFields().length;
 
@@ -1222,6 +1221,83 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
     return transformName;
   }
 
+  private Button getWbbLoopPathList(Composite composite) {
+    Button wbbLoopPathList = new Button(composite, SWT.PUSH | SWT.CENTER);
+    props.setLook(wbbLoopPathList);
+    wbbLoopPathList.setText(BaseMessages.getString(PKG, "GetXMLDataDialog.LoopPathList.Button"));
+    wbbLoopPathList.setToolTipText(
+        BaseMessages.getString(PKG, "System.Tooltip.BrowseForFileOrDirAndAdd"));
+    FormData fdbLoopPathList = new FormData();
+    fdbLoopPathList.right = new FormAttachment(100, 0);
+    fdbLoopPathList.top = new FormAttachment(0, 0);
+    wbbLoopPathList.setLayoutData(fdbLoopPathList);
+    return wbbLoopPathList;
+  }
+
+  private void getFromSnippet() {
+
+    EnterTextDialog getFromSnippetDialog =
+            new EnterTextDialog(
+                    shell,
+                    BaseMessages.getString(PKG, "GetXMLDataDialog.Button.SelectFieldsSnippet"),
+                    BaseMessages.getString(PKG, "GetXMLDataDialog.GetFieldsFromSnippet.Message"),
+                    "",
+                    true) {
+
+              @Override
+              public void enrich(EnterTextDialog enterTextDialog) {
+
+                readSnippetPdOption=new PdOption();
+                readSnippetPdOption.setUseSnippet(true);
+
+                Button wbbLoopPathList = getWbbLoopPathList(enterTextDialog.getShell());
+                wbbLoopPathList.addSelectionListener(
+                        new SelectionAdapter() {
+                          @Override
+                          public void widgetSelected(SelectionEvent e) {
+                            LoopNodesImportProgressDialog pd = new LoopNodesImportProgressDialog(enterTextDialog.getShell(), enterTextDialog.getText(), readSnippetPdOption);
+                            populateLoopPaths(enterTextDialog.getText(), pd);
+                            readSnippetPdOption.setLoopXPath(wLoopXPathSnippet.getText());
+                          }
+                        });
+
+                Label wlLoopXPath = new Label(enterTextDialog.getShell(), SWT.RIGHT);
+                wlLoopXPath.setText(BaseMessages.getString(PKG, "GetXMLDataDialog.LoopXPath.Label"));
+                props.setLook(wlLoopXPath);
+                FormData fdlLoopXPath = new FormData();
+                fdlLoopXPath.top = new FormAttachment(0, margin);
+                fdlLoopXPath.left = new FormAttachment(0, 0);
+                wlLoopXPath.setLayoutData(fdlLoopXPath);
+                wLoopXPathSnippet = new TextVar(variables, enterTextDialog.getShell(), SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+                wLoopXPathSnippet.setToolTipText(BaseMessages.getString(PKG, "GetXMLDataDialog.LoopXPath.Tooltip"));
+                props.setLook(wLoopXPathSnippet);
+                FormData fdLoopXPath = new FormData();
+                fdLoopXPath.left = new FormAttachment(wlLoopXPath, margin);
+                fdLoopXPath.right = new FormAttachment(wbbLoopPathList, -margin);
+                wLoopXPathSnippet.setLayoutData(fdLoopXPath);
+
+                FormData fdlDesc = (FormData) enterTextDialog.getWlDesc().getLayoutData();
+                fdlDesc.top = new FormAttachment(wlLoopXPath, 2 * margin);
+
+                enterTextDialog.setWOkListener(e->{
+                  try {
+                    XmlInputFieldsImportProgressDialog prd = new XmlInputFieldsImportProgressDialog(shell, enterTextDialog.getText(), readSnippetPdOption.getLoopXPath(), readSnippetPdOption);
+                    populateFields(prd, SWT.YES);
+                  } catch (HopException ex){
+                    new ErrorDialog(
+                            shell,
+                            BaseMessages.getString(PKG, "GetXMLDataDialog.FailedToGetFields.DialogTitle"),
+                            BaseMessages.getString(PKG, "GetXMLDataDialog.FailedToGetFieldsFromSnippet.DialogMessage"),
+                            ex);
+                  }
+                });
+
+              }
+            };
+    getFromSnippetDialog.open();
+
+  }
+
   private void setXMLStreamField() {
     try {
 
@@ -1345,7 +1421,11 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
                     BaseMessages.getString(PKG, "GetXMLDataDialog.AskURL.Message"));
             url = d.open();
           }
-          populateLoopPaths(meta, url, true, true);
+          readUrlPdOption=new PdOption();
+          readUrlPdOption.setUseUrl(true);
+          readUrlPdOption.setValidating(meta.isValidating());
+          LoopNodesImportProgressDialog pd = new LoopNodesImportProgressDialog(shell, url, readUrlPdOption);
+          populateLoopPaths(url, pd);
 
         } else if (meta.getIsAFile()) {
           // Read file
@@ -1365,7 +1445,11 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
                       + System.getProperty("file.separator")
                       + dialog.getFileName();
             }
-            populateLoopPaths(meta, str, false, false);
+            readFilePdOption=new PdOption();
+            readFilePdOption.setEncoding(meta.getEncoding() == null ? "UTF-8" : meta.getEncoding());
+            readFilePdOption.setValidating(meta.isValidating());
+            LoopNodesImportProgressDialog pd = new LoopNodesImportProgressDialog(shell, str, readFilePdOption);
+            populateLoopPaths(str, pd);
           }
         } else {
           // Read xml
@@ -1379,7 +1463,10 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
                     null);
             xml = d.open();
           }
-          populateLoopPaths(meta, xml, true, false);
+          readXmlPdOption=new PdOption();
+          readXmlPdOption.setValidating(meta.isValidating());
+          LoopNodesImportProgressDialog pd = new LoopNodesImportProgressDialog(shell, xml, readXmlPdOption);
+          populateLoopPaths(xml, pd);
         }
       } else {
 
@@ -1389,7 +1476,12 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
           // Check the first file
 
           if (fileinputList.getFile(0).exists()) {
-            populateLoopPaths(meta, HopVfs.getFilename(fileinputList.getFile(0)), false, false);
+            readHopVfsPdOption=new PdOption();
+            readHopVfsPdOption.setValidating(meta.isValidating());
+            readHopVfsPdOption.setEncoding(meta.getEncoding() == null ? "UTF-8" : meta.getEncoding());
+            String xml = HopVfs.getFilename(fileinputList.getFile(0));
+            LoopNodesImportProgressDialog pd = new LoopNodesImportProgressDialog(shell, xml, readHopVfsPdOption);
+            populateLoopPaths(xml, pd);
           } else {
             // The file not exists !
             throw new HopException(
@@ -1452,7 +1544,8 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
                     BaseMessages.getString(PKG, "GetXMLDataDialog.AskURL.Title"));
             url = enterStringDialog.open();
           }
-          populateFields(meta, url, true, true, clearFields);
+          XmlInputFieldsImportProgressDialog prd = new XmlInputFieldsImportProgressDialog(shell, url, variables.resolve(meta.getLoopXPath()), readUrlPdOption);
+          populateFields(prd, clearFields);
 
         } else if (meta.getIsAFile()) {
           // Read file
@@ -1473,7 +1566,8 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
                       + dialog.getFileName();
             }
           }
-          populateFields(meta, str, false, false, clearFields);
+          XmlInputFieldsImportProgressDialog prd = new XmlInputFieldsImportProgressDialog(shell, str, variables.resolve(meta.getLoopXPath()), readFilePdOption);
+          populateFields(prd, clearFields);
         } else {
           // Read xml
           String xml = XMLSource;
@@ -1486,14 +1580,16 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
                     null);
             xml = d.open();
           }
-          populateFields(meta, xml, true, false, clearFields);
+          XmlInputFieldsImportProgressDialog prd = new XmlInputFieldsImportProgressDialog(shell, xml, variables.resolve(meta.getLoopXPath()), readXmlPdOption);
+          populateFields(prd, clearFields);
         }
       } else {
 
         FileInputList inputList = meta.getFiles(variables);
 
         if (inputList.getFiles().size() > 0) {
-          populateFields(meta, HopVfs.getFilename(inputList.getFile(0)), false, false, clearFields);
+          XmlInputFieldsImportProgressDialog prd = new XmlInputFieldsImportProgressDialog(shell, HopVfs.getFilename(inputList.getFile(0)), variables.resolve(meta.getLoopXPath()), readHopVfsPdOption);
+          populateFields(prd, clearFields);
         }
       }
     } catch (Exception e) {
@@ -2070,31 +2166,24 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
 
   }
 
-  private void populateLoopPaths(
-      GetXmlDataMeta meta, String XMLSource, boolean dynamicXMLSource, boolean useURL) {
+  private void populateLoopPaths(String XMLSource, LoopNodesImportProgressDialog pd) {
     if (Utils.isEmpty(XMLSource)) {
       return;
     }
-    String[] list_xpath = null;
-    LoopNodesImportProgressDialog pd = null;
-    if (dynamicXMLSource) {
-      pd = new LoopNodesImportProgressDialog(shell, meta, XMLSource, useURL);
-    } else {
-      pd =
-          new LoopNodesImportProgressDialog(
-              shell, meta, XMLSource, meta.getEncoding() == null ? "UTF-8" : meta.getEncoding());
-    }
-    if (pd != null) {
-      list_xpath = pd.open();
-      if (list_xpath != null) {
-        EnterSelectionDialog s =
-            new EnterSelectionDialog(
-                shell,
-                list_xpath,
-                BaseMessages.getString(PKG, "GetXMLDataDialog.Dialog.SelectALoopPath.Title"),
-                BaseMessages.getString(PKG, "GetXMLDataDialog.Dialog.SelectALoopPath.Message"));
-        String listxpaths = s.open();
-        if (listxpaths != null) {
+    String[] list_xpath;
+    list_xpath = pd.open();
+    if (list_xpath != null) {
+      EnterSelectionDialog s =
+              new EnterSelectionDialog(
+                      shell,
+                      list_xpath,
+                      BaseMessages.getString(PKG, "GetXMLDataDialog.Dialog.SelectALoopPath.Title"),
+                      BaseMessages.getString(PKG, "GetXMLDataDialog.Dialog.SelectALoopPath.Message"));
+      String listxpaths = s.open();
+      if (listxpaths != null) {
+        if (pd.getOption().isUseSnippet()) {
+          wLoopXPathSnippet.setText(listxpaths);
+        } else {
           wLoopXPath.setText(listxpaths);
         }
       }
@@ -2102,33 +2191,13 @@ public class GetXmlDataDialog extends BaseTransformDialog implements ITransformD
     this.XMLSource = XMLSource;
   }
 
-  private void populateFields(
-      GetXmlDataMeta meta,
-      String XMLSource,
-      boolean dynamicXMLSource,
-      boolean useURL,
-      int clearFields)
-      throws HopException {
+  private void populateFields(XmlInputFieldsImportProgressDialog prd, int clearFields) throws HopException {
     if (Utils.isEmpty(XMLSource)) {
       return;
     }
 
-    XmlInputFieldsImportProgressDialog prd = null;
     RowMetaAndData[] fields = null;
 
-    if (dynamicXMLSource) {
-      prd =
-          new XmlInputFieldsImportProgressDialog(
-              shell, meta, XMLSource, useURL, variables.resolve(meta.getLoopXPath()));
-    } else {
-      prd =
-          new XmlInputFieldsImportProgressDialog(
-              shell,
-              meta,
-              XMLSource,
-              meta.getEncoding() == null ? "UTF-8" : meta.getEncoding(),
-              variables.resolve(meta.getLoopXPath()));
-    }
     if (prd != null) {
       fields = prd.open();
       if (fields != null) {
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/LoopNodesImportProgressDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/LoopNodesImportProgressDialog.java
index 706c5bb..9ef8420 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/LoopNodesImportProgressDialog.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/LoopNodesImportProgressDialog.java
@@ -50,8 +50,6 @@ public class LoopNodesImportProgressDialog {
 
   private Shell shell;
 
-  private GetXmlDataMeta meta;
-
   private String[] Xpaths;
 
   private String filename;
@@ -63,39 +61,36 @@ public class LoopNodesImportProgressDialog {
 
   private int nr;
 
+  private PdOption option;
+
   /**
    * Creates a new dialog that will handle the wait while we're finding out loop nodes for an XML
    * file
    */
   public LoopNodesImportProgressDialog(
-      Shell shell, GetXmlDataMeta meta, String filename, String encoding) {
+      Shell shell, String xmlSource, PdOption option) {
     this.shell = shell;
-    this.meta = meta;
+    this.option=option;
     this.Xpaths = null;
-    this.filename = filename;
-    this.encoding = encoding;
-    this.listpath = new ArrayList<>();
-    this.nr = 0;
-    this.xml = null;
-    this.url = null;
-  }
 
-  public LoopNodesImportProgressDialog(
-      Shell shell, GetXmlDataMeta meta, String xmlSource, boolean useUrl) {
-    this.shell = shell;
-    this.meta = meta;
-    this.Xpaths = null;
-    this.filename = null;
-    this.encoding = null;
-    this.listpath = new ArrayList<>();
-    this.nr = 0;
-    if (useUrl) {
+    if(option.isXmlSourceIsFile()){
+      this.filename = xmlSource;
+      this.xml = null;
+      this.url = null;
+    }else if(option.isUseUrl()){
+      this.filename = null;
       this.xml = null;
       this.url = xmlSource;
-    } else {
+    }else {
+      this.filename = null;
       this.xml = xmlSource;
       this.url = null;
     }
+
+    this.encoding = option.getEncoding();
+    this.listpath = new ArrayList<>();
+    this.nr = 0;
+
   }
 
   public String[] open() {
@@ -152,7 +147,7 @@ public class LoopNodesImportProgressDialog {
       return null;
     }
     // Validate XML against specified schema?
-    if (meta.isValidating()) {
+    if (option.isValidating()) {
       reader.setValidation(true);
       reader.setFeature("http://apache.org/xml/features/validation/schema", true);
     } else {
@@ -269,4 +264,8 @@ public class LoopNodesImportProgressDialog {
       }
     }
   }
+
+  public PdOption getOption() {
+    return option;
+  }
 }
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/PdOption.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/PdOption.java
new file mode 100644
index 0000000..51b4a1a
--- /dev/null
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/PdOption.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.pipeline.transforms.xml.getxmldata;
+
+public class PdOption {
+    private boolean isValidating;
+    private boolean useUrl;
+    private boolean useSnippet;
+    private String encoding;
+    private boolean isXmlSourceFile;
+    private String loopXPath;
+
+    PdOption() {
+        isValidating = false;
+        useUrl = false;
+        useSnippet = false;
+        encoding = null;
+        isXmlSourceFile = false;
+        loopXPath = "";
+    }
+
+    public void setValidating(boolean validating) {
+        isValidating = validating;
+    }
+
+    public void setUseUrl(boolean useUrl) {
+        this.useUrl = useUrl;
+    }
+
+    public void setUseSnippet(boolean useSnippet) {
+        this.useSnippet = useSnippet;
+    }
+
+    //if the encoding is not null, the source must be a file
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+        this.isXmlSourceFile=true;
+    }
+
+    public boolean isValidating() {
+        return isValidating;
+    }
+
+    public boolean isUseUrl() {
+        return useUrl;
+    }
+
+    public boolean isUseSnippet() {
+        return useSnippet;
+    }
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+    public boolean isXmlSourceIsFile() {
+        return isXmlSourceFile;
+    }
+
+    public String getLoopXPath() {
+        return loopXPath;
+    }
+
+    public void setLoopXPath(String loopXPath) {
+        this.loopXPath = loopXPath;
+    }
+}
diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/XmlInputFieldsImportProgressDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/XmlInputFieldsImportProgressDialog.java
index b933d57..23a5ef8 100644
--- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/XmlInputFieldsImportProgressDialog.java
+++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/getxmldata/XmlInputFieldsImportProgressDialog.java
@@ -62,8 +62,6 @@ public class XmlInputFieldsImportProgressDialog {
 
   private Shell shell;
 
-  private GetXmlDataMeta meta;
-
   private String filename;
   private String encoding;
 
@@ -78,41 +76,38 @@ public class XmlInputFieldsImportProgressDialog {
   private String xml;
   private String url;
 
+  private PdOption option;
+
   /**
    * Creates a new dialog that will handle the wait while we're finding out loop nodes for an XML
    * file
    */
   public XmlInputFieldsImportProgressDialog(
-      Shell shell, GetXmlDataMeta meta, String filename, String encoding, String loopXPath) {
-    this.shell = shell;
-    this.meta = meta;
-    this.fields = null;
-    this.filename = filename;
-    this.encoding = encoding;
-    this.nr = 0;
-    this.loopXPath = loopXPath;
-    this.list = new HashSet<>();
-    this.fieldsList = new ArrayList<>();
-  }
+          Shell shell, String xmlSource, String loopXPath, PdOption option) {
 
-  public XmlInputFieldsImportProgressDialog(
-      Shell shell, GetXmlDataMeta meta, String xmlSource, boolean useUrl, String loopXPath) {
     this.shell = shell;
-    this.meta = meta;
-    this.fields = null;
-    this.filename = null;
-    this.encoding = null;
-    this.nr = 0;
+    this.option=option;
     this.loopXPath = loopXPath;
-    this.list = new HashSet<>();
-    this.fieldsList = new ArrayList<>();
-    if (useUrl) {
+
+    if(option.isXmlSourceIsFile()){
+      this.filename = xmlSource;
+      this.xml = null;
+      this.url = null;
+    }else if(option.isUseUrl()){
+      this.filename = null;
       this.xml = null;
       this.url = xmlSource;
-    } else {
+    }else {
+      this.filename = null;
       this.xml = xmlSource;
       this.url = null;
     }
+
+    this.encoding = option.getEncoding();
+    this.nr = 0;
+    this.list = new HashSet<>();
+    this.fieldsList = new ArrayList<>();
+    this.fields = null;
   }
 
   public RowMetaAndData[] open() {
@@ -169,7 +164,7 @@ public class XmlInputFieldsImportProgressDialog {
       return null;
     }
     // Validate XML against specified schema?
-    if (meta.isValidating()) {
+    if (option.isValidating()) {
       reader.setValidation(true);
       reader.setFeature("http://apache.org/xml/features/validation/schema", true);
     } else {
diff --git a/plugins/transforms/xml/src/main/resources/org/apache/hop/pipeline/transforms/xml/getxmldata/messages/messages_en_US.properties b/plugins/transforms/xml/src/main/resources/org/apache/hop/pipeline/transforms/xml/getxmldata/messages/messages_en_US.properties
index f4ff232..aeb74a5 100644
--- a/plugins/transforms/xml/src/main/resources/org/apache/hop/pipeline/transforms/xml/getxmldata/messages/messages_en_US.properties
+++ b/plugins/transforms/xml/src/main/resources/org/apache/hop/pipeline/transforms/xml/getxmldata/messages/messages_en_US.properties
@@ -56,6 +56,7 @@ GetXMLDataDialog.ErrorPreviewingData.DialogMessage=An error occurred while tryin
 GetXMLDataDialog.Content.Tab=Content
 GetXMLDataField.ElementType.Node=Node
 GetXMLDataDialog.FailedToGetFields.DialogMessage=Can not get fields from previous transform\!
+GetXMLDataDialog.FailedToGetFieldsFromSnippet.DialogMessage=Can not get fields from previous transform\!
 GetXMLDataDialog.NameSpaceAware.Tooltip=Make the document namespace aware
 GetXMLDataDialog.readUrl.Tooltip=Read source as Url
 GetXMLDataDialog.FilenameEdit.Tooltip=Edit the selected file and remove from the list.
@@ -133,6 +134,8 @@ GetXMLDataDialog.Log.GettingFieldsInfo=getting fields info...
 GetXMLData.Log.FinishedProcessing=Finished processing files.
 GetXMLDataDialog.NumberRows.DialogMessage=Enter the number of rows you would like to preview\:
 GetXMLDataDialog.GetFields.Button=\ &Get fields
+GetXMLDataDialog.Button.SelectFieldsSnippet=Select fields from snippet
+GetXMLDataDialog.GetFieldsFromSnippet.Message=Give XML text and the fields can be parsed and extracted.
 GetXMLDataDialog.FilenameRemove.Tooltip=Delete the selected entries from the list of files.
 GetXMLData.Log.LoopXPath=Looping Xpath is \: {0}
 GetXMLDataDialog.wXmlStreamField.Tooltip=Check this option if XML source is defined in previous transforms.
diff --git a/ui/src/main/java/org/apache/hop/ui/core/dialog/EnterTextDialog.java b/ui/src/main/java/org/apache/hop/ui/core/dialog/EnterTextDialog.java
index 2ebcb2a..f5162f8 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/dialog/EnterTextDialog.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/dialog/EnterTextDialog.java
@@ -24,6 +24,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.WindowProperty;
+import org.apache.hop.ui.core.widget.FormInput;
 import org.apache.hop.ui.hopgui.file.workflow.HopGuiWorkflowGraph;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
 import org.eclipse.swt.SWT;
@@ -46,6 +47,7 @@ public class EnterTextDialog extends Dialog {
   private final String title;
   private final String message;
 
+  private Label wlDesc;
   private Text wDesc;
   private Button wOk;
   private final Shell parent;
@@ -143,7 +145,7 @@ public class EnterTextDialog extends Dialog {
     }
 
     // From transform line
-    Label wlDesc = new Label(shell, SWT.NONE);
+    wlDesc = new Label(shell, SWT.NONE);
     wlDesc.setText(message);
     props.setLook(wlDesc);
     FormData fdlDesc = new FormData();
@@ -171,6 +173,12 @@ public class EnterTextDialog extends Dialog {
     wDesc.setLayoutData(fdDesc);
     wDesc.setEditable(!readonly);
     wDesc.addListener(SWT.DefaultSelection, e -> ok());
+    wDesc.addListener(SWT.Modify, e -> {
+      Text source = (Text) e.widget;
+      this.text = source.getText();
+    });
+
+    enrich(this);
 
     // Detect [X] or ALT-F4 or something that kills this window...
     shell.addShellListener(
@@ -264,4 +272,29 @@ public class EnterTextDialog extends Dialog {
   public void setFixed(boolean fixed) {
     this.fixed = fixed;
   }
+
+  //An enrich method is provided for enrich the shell. By default, it does nothing.
+  public void enrich(EnterTextDialog enterTextDialog) {
+  }
+
+  public Label getWlDesc() {
+    return wlDesc;
+  }
+
+  public Text getwDesc() {
+    return wDesc;
+  }
+
+  public Shell getShell() {
+    return shell;
+  }
+
+  @Override
+  public String getText() {
+    return text;
+  }
+
+  public void setWOkListener(Listener listener){
+    wOk.addListener(SWT.Selection, listener);
+  }
 }