Nested CDATA - correctly
Asked Answered
T

3

8

That's problem in XML document:

<![CDATA[<b>Title</b> 
       Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
       tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
       quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
       consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
       cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
       proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
]]>

I need to insert thу CDATA expression in this text. How to do it ? (I see the error while evaluationg document if I do like this)

<![CDATA[]]]]>Expression<![CDATA[>]]>
Torras answered 13/12, 2012 at 17:37 Comment(6)
You can't nest CDATA sections. Why would you need to?Expurgatory
I believe that if you think a bit more about what you are doing, you will find an alternate way to do what you need. en.wikipedia.org/wiki/CDATA#NestingExpurgatory
And that's not really answering the question. Why, in your report, do you need to nest CDATA sections?Expurgatory
Thanks for link. And what explainion do you need? Just becouse of I have report engine which creates the text in CDATA, and in this CDATA I need to insert calculable expression.Torras
Well, you already have a CDATA section. Not sure why you would need to nest anything.Expurgatory
Here's a case where this would be useful: Suppose one has an XML with a CDATA in it, and he wants to take that XML and load it into a node of another XML document, that itself has a CDATA wrapper.Stuffy
S
10

@Oded posted a reference real answer above in a comment... I want to add it as an answer so people can find it.
If he/she adds it we can delete this one.

Yes, it is important to be really sure you need to do this; "CDATA" is often misused in the first place, let alone nested. But in some funky occasions we do.

-

The basic plan is to bury the end of the nested CDATA in another CDATA. It will be stripped with interpretation of the outer CDATA to leave the inner.

This is in the wikipedia article from @Oded above
en.wikipedia.org/wiki/CDATA#Nesting

The action is to replace any inner, nested

]]>

with

]]]]><![CDATA[>
Snyder answered 14/4, 2014 at 19:54 Comment(0)
G
2

I can give you a scenario where it happened for me. I had a SharePoint Content Editor web part that was exported as a .dwp (which has content wrapped in a CDATA) and needed to insert this into a Visual Studio deployment package, the target spot for this in the Elements.xml file is also a CDATA. It's a bit silly because it's just HTML in XML in XML but then it's SharePoint so silly is the normal state of being.

So just in case this leads someone else to this page I thought I'd summarise the solutions I came up with:

1) XML encode the inner CDATA so you don't need the inner CDATA. Might not always be practical but worked in my case.

2) In this case there was a another option, move the content of the Content Editor web part to a separate file and link the Content Editor to that web part file. I guess this falls under the rethink your strategy approach.

3) The above idea of splitting the whole CDATA into three separate consecutive CDATAs. While this is a clever idea and would work for general cases, I'm not sure this would work in my case. This is because the content was going to be passed by 2 different processes, the deployer and then the page manager. The deployer needed to take the content of the outer CDATA and pass it whole to the page manager which would then take the content of the CDATA as a single element value. With the 3 CDATA approach the deployer would have treated the whole content as a single XML structure and so the HTML actually gets interpretted incorrectly. (I hope that makes sense).

Genealogy answered 7/11, 2013 at 20:56 Comment(0)
D
0

hi this functions add to string object in javascript and you can use this for any string . the end of this code show you how use this for solve your broblem (seiied mahmood mirkhalili([email protected] ))

    /**
     * replace pattern with relative of nested pattern (a pattern in another patern)
     * @param  {string} input  [match of regreplace]
     * @param  {string} input1 [match firstgroup of regreplace ]
     * @param  {string} input2 [match second group of regreplace ]
     * @return {string}        [replace string with pattern ]
     */
    String.prototype.relativeInnerReplaceFunction = function (input , input1 , input2){
      var firstMatch = input1.match(this.regfirst);
      if(firstMatch != undefined){
        firstMatch = firstMatch.length
      } else {
        firstMatch = 0 ;
      }
      var lastMatch = input1.match(this.regEnd);
      if(lastMatch != undefined){
        lastMatch = lastMatch.length ;
      } else {
        lastMatch = 0 ;
      }
      if(input1 != undefined && input1 != 404){
        var relativeInnerReplaceFunction = this.relativeInnerReplaceFunction.bind(this);
        input1 = input1.replace(this.regReplace , relativeInnerReplaceFunction) ; 
      }
      var numLoop = firstMatch - lastMatch - 1;
      if(input2 != undefined){
        for (var i = 0; i < numLoop; i++) {
          input2 = input2.replace(this.regReplace , this.pattern);
        }
      } else {
        input2 = '' ;
      }
      return input1+input2 ;
    };
    /**
     * replace recuresive pattern for solve problem cdata in cdata mor info in this link   https://mcmap.net/q/1295457/-nested-cdata-correctly
     * @param  {regular experssion} regfirst   [the start pattern ]
     * @param  {regular experssion} regEnd     [the end pattern ]
     * @param  {regular experssion} regReplace [the pattern for nested replace]
     * @param  {string} pattern [the pattern will replace with regReplce regular pattern in nested replace]
     * @return {string}            [string after calculate nested pattern and replace with regreplace ]
     */
    String.prototype.relativeInnerReplace = function (regfirst , regEnd, regReplace , pattern){
      this.regfirst = regfirst ;
      this.regEnd = regEnd ;
      this.regReplace = regReplace ;
      this.pattern = pattern ;
      var relativeInnerReplaceFunction = this.relativeInnerReplaceFunction.bind(this);
      var output = this.replace(regReplace , relativeInnerReplaceFunction) ;
      return output ;
    }

/*how to use
  for example for nested cdata problem 'search in stackoverflow'
 wpsExample.relativeInnerReplace(/<!\[CDATA\[/g , /\]\]>/g , /^(.*)(\]\]>)/g , '$1]]]]><![CDATA[>')
 */
Deucalion answered 28/1, 2018 at 5:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.