xslt - XML to XML transform based on attribute value of previous sibling and ancestor to parent -
note: edited make elements , attribute values visible (they invisible before because used angle brackets) , provide complete sample xml source file.
i'm trying create xsl complex xml xml transform.
i have xml has text elements <a:t> have various paths start either /p:sld or /p:notes end /p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t.
these <a:t> elements need transformed different target xml elements based on how path starts , attribute value of (sometimes present) preceding sibling <a:ppr> <a:r> in turn parent <a:t>.
here's minimal version of of source xml example: http://pastie.org/9559309
here xpaths of various <a:t> elements , target xml them. edit: added new item @ start of items paths start /p:notes
- xpath
/p:sld/p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t<body> - xpath
/p:sld/p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t(<a:r>tag preceded<a:ppr lvl="1">)<bulleted> - xpath
/p:sld/p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t(<a:r>tag preceded<a:ppr lvl="2">)<bulleted2> - xpath
/p:notes/p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t<body> - xpath
/p:notes/p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t(<a:r>tag preceded sibling<a:ppr lvl="1">)<body> - xpath
/p:notes/p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t(<a:r>tag preceded sibling<a:ppr lvl="2">)<bulleted> - xpath
/p:notes/p:csld/p:sptree/p:sp/p:txbody/a:p/a:r/a:t(<a:r>tag preceded sibling<a:ppr lvl="3">)<bulleted2>
note how it's interaction of start of path , attribute value of <a:ppr> when <a:ppr> present determines xml element output. example:
element <a:t> parent <a:r> preceded <a:ppr "lvl=1"> should produce <bulleted> if source xpath starts /p:sld if source path starts /p:notes <a:t> tag else same should <body> in output.
finally, need transform couple of elements near root xpath /p:notes <pagebreak> , xpath /p:sld <pagebreak>.
the output xml should this. edit: matches content of source xml.
<document> <pagebreak></pagebreak> <bodytext>activity 1:</bodytext> <bodytext>services platform</bodytext> <bodytext>objective :</bodytext> <bulleted>the objective of activity identify services each node supports</bulleted> <bodytext>description :</bodytext> <bulleted>this individual activity. using information covered , drawing on next page fill in table information requested instructor</bulleted> <bodytext>ig: mandatory individual activity. time: 5 – 10 min.</bodytext> <pagebreak></pagebreak> <bodytext>2</bodytext> <bodytext>activity 1: </bodytext> <bodytext>services platform</bodytext> <bodytext>to complete activity, use following material:</bodytext> <bulleted>the drawing , table on next page, along information provided instructor.</bulleted> </document> <pagebreak> empty element, <bodytext> , <bullet> elements contain text relevant <a:t> in source xml, other elements source xml stripped.
update: i've written xsl seems should work take contents of each a:t element in input xml , put appropriate output element name around on output. body changed bodytext don't issues body being reserved html word.
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:fo="http://www.w3.org/1999/xsl/format" xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officedocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"> <xsl:template match="/"> <xsl:for-each select="//a:t/"> <xsl:choose> <xsl:when test="(count(ancestor::p:sld) > 0) , (count(ancestor::a:r[preceding-sibling[1]@lvl='1']) > 0"> <bulleted><xsl:value-of select="."/></bulleted> </xsl:when> <xsl:when test="(count(ancestor::p:sld) > 0) , (count(ancestor::a:r[preceding-sibling[1]@lvl='2']) > 0"> <bulleted2><xsl:value-of select="."/></bulleted2> </xsl:when> <xsl:when test="(count(ancestor::p:notes) > 0) , (count(ancestor::a:r[preceding-sibling[1]@lvl='2']) > 0"> <bulleted><xsl:value-of select="."/></bulleted> </xsl:when> <xsl:when test="(count(ancestor::p:notes) > 0) , (count(ancestor::a:r[preceding-sibling[1]@lvl='3']) > 0"> <bulleted><xsl:value-of select="."/></bulleted> </xsl:when> <xsl:otherwise> <bodytext><xsl:value-of select="."/></bodytext> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:template> </xsl:stylesheet> i'm getting syntax errors transform related fact a:t uses prefix i'm not sure how fix errors.
i'm not sure how tell transform xsl processor put pagebreak on output each p.sld or p.notes element appears on input , have show @ proper place. seems should maybe make outer "for-each /document/p.sld or /document/p.notes" command
- outputs
<pagebreak></pagebreak>tag pair - then starts inside for-each
a:tin code above, limited scope ofp.sldorp.noteselement selected outside for-each - then closes outside for-each command sending processor next
p.sldorp.notesin source xml.
thanks can provide.
Comments
Post a Comment