David Garcia
David Garcia

Reputation: 2696

Regex: Javascript, XML, String

I have the following data in a variable.

<ctx>
  <PostCode>XXXXXX</PostCode>
  <Title1>Mr</Title1>
  <Name>John</Name>
  <Order1>£100.00</Order1>
  <Order2>£100.01</Order2>
  <Date>10/10/2010</Date
</ctx>

Using the following regex var payload = ctx.toString().match(/Order[1-9]/g); I get the following results

Order1,Order1,Order2,Order2

How can I make it stop at Order1, Order2 as is counting the second closing tag, also I can't use <Order[1-9]> (opening tag) as my application does not allow me to capture the tags <>. Basically a regex that returns unique values.

So the following regex seems to work to some extend. (Order[0-9])(?!.*\1) (Order[0-9])(?!.*\1)

https://regex101.com/r/6QhFBg/1

Upvotes: 0

Views: 138

Answers (2)

kjhughes
kjhughes

Reputation: 111521

Never parse XML with regex. Wrong tool for the job – leads to brittle solutions.

Instead, use a real XML parser or XPath.

For example, this XPath,

//*[starts-with(local-name(), 'Order')]

will robustly select all elements whose name starts with "Order".

In JavaScript in the browser, XPath expressions are evaluated via document.evaluate:

var orders = document.evaluate('//Order[starts-with(local-name(), 'Order')]', document, 
                               null, XPathResult.ANY_TYPE, null );
var thisOrder = orders.iterateNext();

while (thisOrder) {
  console.log(thisOrder.textContent);
  thisOrder = orders.iterateNext();
}

See also How to use document.evaluate() and XPath to get a list of elements?

For parsing XML stored in a string, see for example:

Upvotes: 2

junvar
junvar

Reputation: 11574

let ctx = 
`<ctx>
  <PostCode>XXXXXX</PostCode>
  <Title1>Mr</Title1>
  <Name>John</Name>
  <Order1>£100.00</Order1>
  <Order2>£100.01</Order2>
  <Date>10/10/2010</Date
</ctx>`;

let payload = ctx
  .match(/<Order[1-9]>/g) // e.g. <Order1>
  .map(o => o.substring(1, o.length - 1)); // trim first char `<` and last char `>`

console.log(payload);

Upvotes: 1

Related Questions