Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

XML tag closing

by maha (Novice)
on Jan 06, 2012 at 04:17 UTC ( #946523=perlquestion: print w/replies, xml ) Need Help??
maha has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,

i want to close </book-part> tag before the next chapter tag beginning


<book-part book-part-type="chapter" book-part-number="\d+" id="chapter\d+">

its a beginning tag of each chapter.

"</book-part>" should close before next chapter's opening tag,(i.e)</book-part> is an ending tag of each chapter

plz give some suggestion, thank u monks

i try below code but i does't show any changes

if($str =~ /<book-part book-part-type="chapter" id="chapter\d+">((?:(? +!<\/?book-part book-part-type="chapter" id="chapter\d+">).)*)(?=<book +-part book-part-type="chapter" id="chapter\d+">)/sgi) { $str .="<book-part>"; }

my output generate in below

</book-part> <book-part book-part-type="chapter" book-part-number="2" id="chapter2" +>

"</book-part>" this is first chapter's closing and "<book-part book-part-type="chapter" book-part-number="2" id="chapter2">" this is second chapter opening

Replies are listed 'Best First'.
Re: XML tag closing
by tobyink (Abbot) on Jan 06, 2012 at 07:14 UTC

    Don't write XML using string concatenation - you'll always make mistakes. Build a DOM using something like XML::LibXML, then serialize it.

Re: XML tag closing (naive way)
by tye (Sage) on Jan 06, 2012 at 06:09 UTC
    my $xmlish = <<'END'; <whatever><book-part type='closed'> Chapter 1 </book-part> <book-part type='unclosed'> Chapter 2 <book-part type='final'> Chapter 3 </whatever> END my $prev = '/'; $xmlish =~ s{(?=<\s*(/?)\s*book-part\b)}{ ( ! $prev && ! $1 ? '</book-part>' : '', $prev= $1, )[0] }ge; print $xmlish; __END__ <whatever><book-part type='closed'> Chapter 1 </book-part> <book-part type='unclosed'> Chapter 2 </book-part><book-part type='final'> Chapter 3 </whatever>

    Assumes no <book-part bits inside attribute values, comments, nor CDATA blocks, of course. Not using an XML parser since missing closing tags means you don't really have XML that a real XML parser would handle. Also note how it doesn't insert a final closing tag (you didn't provide enough information for me to know how to do that for your case).

    - tye        

      i got the solution tye,and its working properly

      if($line =~ /(<book-part[^>]*>)((?:(?!<book-part[^>]*>).)*)(?=<book-pa +rt[^>]*>|$)/sgi) { $line .="</book-part>\n"; }

      sorry tye,

      i'm not native English speaker,ur code is working but i have lots of content, tags inside the chapter,i want to close book part after the content and the ending of the content there is no constant tag to fix an origin,can i mention the ending of the content by $ symbol or u can give some more suggestion to close

      thanks for concerning my problem

        Please think of this as a constructive reply (rather than critisiscm):

        Even if you are not a native english speaker (neither am i or many other monks here), please try to use english, not ircspeak (use "you" instead of "u", "your" instead of "ur" and so on). It would make for an easier read and will also show that you are at least trying.

        This in turn will have the effect that more people will be willing to read your whole post and reply with an answer.

        "Believe me, Mike, I calculated the odds of this succeeding against the odds I was doing something incredibly stupidů and I went ahead anyway." (Crow in "MST3K The Movie")

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://946523]
Approved by GrandFather
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2018-05-21 23:24 GMT
Find Nodes?
    Voting Booth?