XML to XML conversion based on the value of the previous sibling and ancestor attribute for the parent

Note. Edited to make elements and attribute values ​​visible (they were not visible before because I used angle brackets) and to provide a complete sample XML source file.

I am trying to create XSL to perform complex XML-XML transformation.

I have an XML that has some text elements <a:t>

that have different paths that start with /p:sld

or /p:notes

but always end with /p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t

.

These elements <a:t>

must be converted to different target XML elements based on how the path begins and the value of the (sometimes present) attribute preceding the sibling <a:pPr>

on <a:r>

, which in turn is the parent of <a:t>

.

Here's a minimal version of the original XML, for example: http://pastie.org/9559309

Here are the xpaths of the various elements <a:t>

and the target XML for them. Edit: I added a new item at the start of items whose 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

    (tag <a:r>

    preceded by <a:pPr lvl="1">

    )) to<Bulleted>

  • xpath /p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t

    (tag <a:r>

    preceded by <a:pPr lvl="2">

    )) to<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

    (tag <a:r>

    preceded by sibling <a:pPr lvl="1">

    ) to<Body>

  • xpath /p:notes/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t

    (tag <a:r>

    preceded by sibling <a:pPr lvl="2">

    ) to<Bulleted>

  • xpath /p:notes/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t

    (tag <a:r>

    preceded by sibling <a:pPr lvl="3">

    ) to<Bulleted2>

Notice how the start of the path interaction is present and the attribute value <a:pPr>

, when <a:pPr>

present, that determines which xml element is rendered. For example:

The immediately preceded <a:t>

parent should create if the original xpath starts But if the original path starts with a tag with everything else, then it should be in the output.<a:r>

<a:pPr "lvl=1">

<Bulleted>

/p:sld

/p:notes

<a:t>

<Body>

Finally, I also need to convert a couple of elements near the root xpath /p:notes

to <PageBreak>

and xpath /p:sld

to <PageBreak>

.

The output XML should look like this. Edit: This now matches the content of the original xml.

<Document>
<PageBreak></PageBreak>
<bodytext>Activity 1:</bodytext>
<bodytext>Services Platform</bodytext>
<bodytext>Objective :</bodytext>
<Bulleted>The objective of this activity is to identify which services each node supports</Bulleted>
<bodytext>Description :</bodytext>
<Bulleted>This will be an individual activity. Using the information we just covered and the drawing on the next page fill in the table with the information requested by your 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 this activity, use the following material:</bodytext>
<Bulleted>The drawing and table on the next page, along with the information provided by your Instructor.</Bulleted>
</Document>

      

<PageBreak>

- empty element, elements <bodytext>

and <Bullet>

contain text from the corresponding <a:t>

in the source XML, all other elements from the source XML are stripped.

UPDATE: I wrote some xsl that seems to work on the content of each a: t element in the input xml and put the corresponding output element name around it in the output. The body was changed to bodytext, so I don't get any problems with the body being a 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) and (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) and (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) and (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) and (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 am getting syntax errors from Transform related to which a:t

prefix is ​​used, which I am not sure how to fix these errors.

I'm also not sure how to tell the XSL Transform Processor to put the page output in the output where each p.sld or p.notes element appears in the input and they appear in the right place. It seems that I have to make an external command "for-each / document / p.sld or /document/p.notes" which

  • outputs a couple of tags <pagebreak></pagebreak>

  • then triggers another one internally for each a:t

    , as in the above code, but limited to the scope of the item p.sld

    or p.notes

    currently selected external for each
  • then closes the outside for each command sending the processor to find the next p.sld

    or p.notes

    in the original xml.

Thanks for any help you can provide.

+3


source to share





All Articles