0

I am looking for a way to create a new node from existing node and remove the searched string from existing node.

Example:

<RSS>
<ITEM>
      <PRODUCT_ID>86258</PRODUCT_ID>
      <EAN>8595174240939</EAN>
      <PRODUCT_NAME>Apple T-Shirt, 16"</PRODUCT_NAME>
</ITEM>
<ITEM>
      <PRODUCT_ID>86255</PRODUCT_ID>
      <EAN>8595174240931</EAN>
      <PRODUCT_NAME>Orange T-Shirt, 18"</PRODUCT_NAME>
</ITEM>
</RSS>

I would like to search for 16", 18" in the example above, I think regex \d+"$ (number + " + end of string) would do the trick. In the next step I would like to cut this searched string with the comma (,.*\d+"$)

Output.xml:

<RSS>
<ITEM>
      <PRODUCT_ID>86258</PRODUCT_ID>
      <EAN>8595174240939</EAN>
      <PRODUCT_NAME>Apple T-Shirt</PRODUCT_NAME>
      <SIZE>16"</SIZE>
</ITEM>
<ITEM>
      <PRODUCT_ID>86255</PRODUCT_ID>
      <EAN>8595174240931</EAN>
      <PRODUCT_NAME>Orange T-Shirt</PRODUCT_NAME>
      <SIZE>18"</SIZE>
</ITEM>
</RSS>
1
  • What language are you using? Java, python, c#. Do you have a code example you are using? Commented Dec 5, 2019 at 19:20

2 Answers 2

2

To apply this change using RegEx'es, you have to use XSLT-2.0, like this:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

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

  <xsl:template match="PRODUCT_NAME">
    <xsl:analyze-string select="." regex='(.*?),?\s?(\d{{2}}")$'>
      <xsl:matching-substring>
        <PRODUCT_NAME><xsl:value-of select="regex-group(1)" /></PRODUCT_NAME>
        <SIZE><xsl:value-of select="regex-group(2)" /></SIZE>
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <PRODUCT_NAME><xsl:copy-of select="." /></PRODUCT_NAME>
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </xsl:template>

</xsl:stylesheet>

Its output is:

<?xml version="1.0" encoding="UTF-8"?>
<RSS>
   <ITEM>
      <PRODUCT_ID>86258</PRODUCT_ID>
      <EAN>8595174240939</EAN>
      <PRODUCT_NAME>Apple T-Shirt</PRODUCT_NAME>
      <SIZE>16"</SIZE>
   </ITEM>
   <ITEM>
      <PRODUCT_ID>86255</PRODUCT_ID>
      <EAN>8595174240931</EAN>
      <PRODUCT_NAME>Orange T-Shirt</PRODUCT_NAME>
      <SIZE>18"</SIZE>
   </ITEM>
</RSS>
Sign up to request clarification or add additional context in comments.

Comments

0

This would give you the desired output:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

    <xsl:template match="ITEM">
        <xsl:copy>
            <xsl:apply-templates/>
            <xsl:if test="contains(PRODUCT_NAME,'T-Shirt')">
                <SIZE><xsl:value-of select="substring-after(PRODUCT_NAME,', ')"/></SIZE>
            </xsl:if>
       </xsl:copy>
    </xsl:template>

    <xsl:template match="PRODUCT_NAME[contains(.,'T-Shirt')]">
        <PRODUCT_NAME><xsl:value-of select="substring-before(.,',')"/></PRODUCT_NAME>
    </xsl:template>

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

</xsl:stylesheet>

You can try it here: https://xsltfiddle.liberty-development.net/bFWR5Eo

1 Comment

The only problem product name can be anything and can contain multiple commas. This is why I am thinking in a regex method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.