Accesing only immediate preceding sibling in xslt - xslt

I am using XSLT 1.0. Currently am in <w:t> template. I want to check if the preceding sibling w:r(id=3) has <w:fldChar w:fldCharType="end"/>.
I'm want the immediate preceding sibling only and not w:r having id=2 or id=1.
<t xmlns:w="http://example.com">
<w:r id="1">
<w:fldChar w:fldCharType="start"/>
</w:r>
<w:r id="2">
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:bookmarkStart w:id="0" w:name="tocStartRef_1"/>
<w:r id="3">
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:bookmarkEnd w:id="0"/>
<w:r id="4">
<w:rPr>
<w:rStyle w:val="Span"/>
<w:rFonts w:ascii="arial" w:eastAsia="arial"
w:hAnsi="arial" w:cs="arial"/>
<w:b/>
<w:sz w:val="32"/>
</w:rPr>
<w:t>Fonts</w:t>
</w:r>
</t>

Use the xpath preceding-sibling axis like this:
preceding-sibling::w:r[1]/w:fldChar/#w:fldCharType = 'end'
which will select the nearest ([1]) preceding-sibling named w:r, then descend to any child element(s) named w:fldChar, then any attributes from there named w:fldCharType, then if any such node exists whose text is 'end', returns true.

Related

xsl:for-each repeating the first row

i left out the for-each end statements in previous post: here is a snap shot of the doc and the xsl including the end stmts. i made a change to code (removed the inline "<for-each end>" which changed the results. Now, there are two answers for each question BUT the first row is no longer repeated.
Document:
for-each-groupEXAM_QSTN_TXT
for-eachEXAM_ANSWR_TXT end end
BI Pub xsl dialog boxes:
<xsl:for-each-group select=".//row" group-adjacent="EXAM_QSTN_RECID">
<?for-each:current-group()?><?EXAM_ANSWR_TXT?>
<?end for-each?>
<?end for-each-group?>
New Result:
Test question text
TrueTrue
FalseFalse
/*****************************************************************/
Creating a template using Word w/BI Publisher. New to xsl code. Within a for-each-group, i have a for-each loop that is erroneously repeating the first row. Each record has the group value AND the child value. Data consists of each record containing: an exam question and answer text (with 2 - 4 "rows" as possible answers). The first "row" is used as the "exam question txt" in the for-each-group. The first row is ALSO the "first possible answer" in the for-each loop. Problem: the first (row) which is a possible answer is repeated at the end of the loop so template shows 5 possible answers not 4 (or in the example below 3 instead of 2 possible). Your help is greatly appreciated.
Here's the code:
<xsl:for-each-group select=".//row" group-adjacent="EXAM_QSTN_RECID">
<?for-each:current-group()?><?EXAM_ANSWR_TXT?><?end for-each?>
output:
True False question text
True
False
True
XML Word generated code:
<w:textInput>
<w:default w:val="for-each-group"/>
</w:textInput>
</w:ffData>
</w:fldChar>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:instrText xml:space="preserve"> FORMTEXT </w:instrText>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:noProof/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:t>for-each-group</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:bookmarkEnd w:id="0"/>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Text1"/>
<w:enabled/>
<w:calcOnExit w:val="0"/>
<w:statusText w:type="text" w:val="<?ref:xdo0018?>"/>
<w:textInput>
<w:default w:val="EXAM_QSTN_TXT"/>
</w:textInput>
</w:ffData>
</w:fldChar>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:instrText>FORMTEXT</w:instrText>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:noProof/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:t>EXAM_QSTN_TXT</w:t>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:t xml:space="preserve"> </w:t>
</w:r>
<w:bookmarkStart w:id="1" w:name="Text5"/>
<w:r w:rsidR="00887F5C">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Text5"/>
<w:enabled/>
<w:calcOnExit w:val="0"/>
<w:statusText w:type="text" w:val="<?ref:xdo0006?>"/>
<w:textInput>
<w:default w:val="for-each"/>
</w:textInput>
</w:ffData>
</w:fldChar>
</w:r>
<w:r w:rsidR="00887F5C">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:instrText xml:space="preserve"> FORMTEXT </w:instrText>
</w:r>
<w:r w:rsidR="00887F5C">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
</w:r>
<w:r w:rsidR="00887F5C">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r w:rsidR="00887F5C">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:noProof/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:t>for-each</w:t>
</w:r>
<w:r w:rsidR="00887F5C">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:bookmarkEnd w:id="1"/>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Text1"/>
<w:enabled/>
<w:calcOnExit w:val="0"/>
<w:statusText w:type="text" w:val="<?ref:xdo0019?>"/>
<w:textInput>
<w:default w:val="EXAM_ANSWR_TXT"/>
</w:textInput>
</w:ffData>
</w:fldChar>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:instrText>FORMTEXT</w:instrText>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:noProof/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:t>EXAM_ANSWR_TXT</w:t>
</w:r>
<w:r w:rsidR="00360D93">
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="end"/>
</w:r>
<w:bookmarkStart w:id="2" w:name="Text2"/>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
<w:sz w:val="24"/>
<w:szCs w:val="24"/>
</w:rPr>
<w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Text2"/>
<w:enabled/>
<w:calcOnExit w:val="0"/>
<w:statusText w:type="text" w:val="<?ref:xdo0001?>"/>
<w:textInput>
<w:default w:val="end"/>
</w:textInput>
</w:ffData>
</w:fldChar>
</w:r>
<w:r>
Figured it out: XSL in Word w/BI Publisher:
Document:
for-each-group EXAM_QSTN_TXT
for-each EXAM_ANSWR_TXT end end
BI Pub dialog box for code:
<xsl:for-each-group select=".//row" group-adjacent="EXAM_QSTN_RECID">
<?for-each-group:current-group();./EXAM_ANSWR_RECID?>
<?end for-each-group?>
<?end for-each-group?>
Produces:
Test Question Text
multiple choice answer 1
multiple choice answer 2
etc.

How can convert the nested section DOCX file in to the XML using - XSLT

How can convert DOCX section style (e.g. Titre-niv1,Titre-niv2, Titre-niv3) and (e.g. Paragraphesimple style into the Paragraphenum-Titrenoy) convert to XML nested section and para XML.
Input
<root xmlns:w="www.ap">
<w:p w:rsidR="00A13CB1" w:rsidRDefault="000F7DF9" w:rsidP="00AE46E9">
<w:pPr>
<w:pStyle w:val="Titre-niv1"/>
</w:pPr>
<w:r w:rsidRPr="00C135AA">
<w:t>Contentieux sur la validit du brevet</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A13CB1" w:rsidRDefault="000F7DF9" w:rsidP="00AE46E9">
<w:pPr>
<w:pStyle w:val="Titre-niv2"/>
</w:pPr>
<w:r w:rsidRPr="00C135AA">
<w:t>Dlai de restauration</w:t>
</w:r>
</w:p>
<w:p w:rsidR="00A13CB1" w:rsidRDefault="00A13CB1" w:rsidP="00AE46E9">
<w:pPr>
<w:pStyle w:val="Paragraphenum-Titrenoy"/>
</w:pPr>
</w:p>
<w:p w:rsidR="00A13CB1" w:rsidRDefault="000F7DF9" w:rsidP="00AE46E9">
<w:pPr>
<w:pStyle w:val="Paragraphesimple"/>
<w:rPr>
<w:color w:val="000000"/>
<w:shd w:val="clear" w:color="auto" w:fill="FFFFFF"/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="00C135AA">
<w:t>Selon l</w:t>
</w:r>
<w:r w:rsidR="00963C32">
<w:t>'</w:t>
</w:r>
<w:r w:rsidRPr="00C135AA">
<w:t>article L. 612-16 du Code de la propri intellectuelle, en cas d</w:t>
</w:r>
</w:p>
</root>
Expected output
<root>
<div1chr>
<tit>
<al>Contentieux sur la validit du brevet</al>
</tit>
<div2chr>
<tit>
<al>Dlai de restauration</al>
</tit>
<pnchr>
<observ>
<al>Selon l'article L. 612-16 du Code de la propri intellectuelle, en cas d</al>
</observ>
</pnchr>
<pnchr>
<observ>
<al>Selon l'article L. 612-16 du Code de la propri intellectuelle, en cas d</al>
</observ>
</pnchr>
</div2chr>
</div1chr>
</root>
You need something along the lines
<xsl:for-each-group select="w:p"
group-starting-with="w:pPr/w:pStyle[w:val='Titre-niv1']">
<div1chr>
<tit>
<xsl:value-of select="current-group()[1]/w:r/w:t"/>
</tit>
<xsl:for-each-group select="remove(current=group(), 1)"
group-starting-with="w:pPr/w:pStyle[w:val='Titre-niv2']">
<div2chr>
<tit>
<xsl:value-of select="current-group()[1]/w:r/w:t"/>
</tit>
<xsl:apply-templates select="remove(current-group(), 1)"/>
</div2chr>
</...
</...
</...

Regular expression that can get tag with some text inside

Here is my example:
<w:p>
<w:pPr>
<w:spacing></w:spacing>
<w:contextualSpacing/>
<w:rPr/>
</w:pPr>
<w:r>
<w:rPr>
<w:color/>
<w:rtl w:val="0"/>
</w:rPr>
<w:t>Some text</w:t>
</w:r>
<w:r>
<w:rPr>
<w:color/>
<w:rtl/>
</w:rPr>
<w:t>My search text</w:t>
</w:r>
<w:r>
<w:rPr>
<w:color/>
<w:rtl/>
</w:rPr>
<w:t>Other text</w:t>
</w:r>
I need to get this block with a regular expression:
<w:r>
<w:rPr>
<w:color/>
<w:rtl/>
</w:rPr>
<w:t>My search text</w:t>
</w:r>
But my regular expression always get first <w:r> and last </w:r>. Lazy quantifiers don`t help.
So how I can get <w:r> </w:r> block only with "My search text" inside?
https://regex101.com/r/2Sh68k/2 Here is the example
here the steps to fix your example
<w:r>.+My search text.+<\/w:r>
adding a non captuiring group around the . of .+ have no effect
<w:r>(?:.)+My search text(?:.)+<\/w:r>
inserting a negative lookahead (?!) before . to prevent the next matching chracter to be the start of not wanted sequence <w:r> or </w:r>
<w:r>(?:(?!<w:r>|<\/w:r>).)+My search text(?:(?!<w:r>|<\/w:r>).)+<\/w:r>
updated link

Working with multiple files using XSLT

I have XML file doc.xml like below:
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:p w:rsidR="002576E5" w:rsidRDefault="006D0E45">
<w:pPr>
<w:pStyle w:val="figure"/>
</w:pPr>
<w:r><w:t xml:space="preserve">Figure 1 </w:t></w:r>
</w:p>
<w:p w:rsidR="002576E5" w:rsidRDefault="006D0E45">
<w:pPr>
<w:pStyle w:val="figure"/>
</w:pPr>
<w:r><w:t xml:space="preserve">Figure 2</w:t></w:r>
</w:p>
</w:document>
In the same location I have another file doc.xml.res
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships /oleObject" Target="embeddings/oleObject1.bin"/>
</Relationship>
</Relationships>
If find each w:p[w:pPr/w:pStyle/#w:val="figure"] using XSLT would like to change the doc.xml.rels file as like below:
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="embeddings/oleObject1.bin"/>
</Relationship>
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="c://1.jpg"/>
</Relationship>
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="c://2.jpg"/>
</Relationship>
</Relationships>
doc.xml should be like below. Would like to add pict element with imagedate r:id according to the Relationship id:
<w:p>
<w:r>
<w:pict>
<v:shape id="myShape2" type="#_x0000_t75" style="width:400; height:240">
<v:imagedata r:id="rId3"/>
</v:shape>
</w:pict>
</w:r>
</w:p>
<w:p w:rsidR="002576E5" w:rsidRDefault="006D0E45">
<w:pPr>
<w:pStyle w:val="figure"/>
</w:pPr>
<w:r><w:t xml:space="preserve">Figure 1 </w:t></w:r>
</w:p>
<w:p>
<w:r>
<w:pict>
<v:shape id="myShape2" type="#_x0000_t75" style="width:400; height:240">
<v:imagedata r:id="rId4"/>
</v:shape>
</w:pict>
</w:r>
</w:p>
<w:p w:rsidR="002576E5" w:rsidRDefault="006D0E45">
<w:pPr>
<w:pStyle w:val="figure"/>
</w:pPr>
<w:r><w:t xml:space="preserve">Figure 2</w:t></w:r>
</w:p>
Is this possible in XSLT?
Yes, this should be possible. result-document allows you to write other files. For reading them, you can use document(uri) function.

How can I make my reg exp less greedy?

I'm trying select a small porting of the XML below but my reg exp doesn't work as expected.
My reg exp
<w:p [^<>]*><w:r><w:t>\[end participant\]<\/w:t><\/w:r><\/w:p>
It should match
<w:p w:rsidRDefault="009C141F" w:rsidP="006003BD">
<w:pPr>
<w:spacing w:after="240" />
</w:pPr>
<w:r>
<w:t>[end participant]</w:t>
</w:r>
</w:p>
But it matches up to the first w:p tag.
Here is the complete XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
<w:body>
<w:p w:rsidRDefault="001660DB" w:rsidP="001660DB">
<w:pPr>
<w:pStyle w:val="Titre1" />
<w:spacing w:before="0" />
</w:pPr>
<w:r>
<w:t>Salut</w:t>
</w:r>
</w:p>
<w:p w:rsidRDefault="001660DB" w:rsidP="001660DB">
<w:pPr>
<w:pStyle w:val="Titre2" />
<w:spacing w:before="0" />
</w:pPr>
<w:r>
<w:t>Hello les gens &àè!</w:t>
</w:r>
</w:p>
<w:p w:rsidRDefault="00F87349" />
<w:p w:rsidRDefault="009C141F">
<w:r>
<w:t>[start participant]</w:t>
</w:r>
</w:p>
<w:p w:rsidRDefault="009C141F" w:rsidP="006003BD">
<w:pPr>
<w:pStyle w:val="Titre1" />
<w:spacing w:before="0" w:after="240" />
</w:pPr>
<w:r>
<w:t xml:space="preserve">Mr #NOM# #PRENOM#</w:t>
</w:r>
</w:p>
<w:p w:rsidRDefault="009C141F" w:rsidP="006003BD">
<w:pPr>
<w:spacing w:after="240" />
</w:pPr>
<w:r>
<w:t>[end participant]</w:t>
</w:r>
</w:p>
<w:sectPr w:rsidSect="00425138">
<w:pgSz w:w="11906" w:h="16838" />
<w:pgMar w:top="1417" w:right="1417" w:bottom="1417" w:left="1417" w:header="708" w:footer="708" w:gutter="0" />
<w:cols w:space="708" />
<w:docGrid w:linePitch="360" />
</w:sectPr>
</w:body>
</w:document>
thanks
I think you're missing the tag for spacing:
<w:p [^<>]*><w:pPr><w:spacing [^<>]*/></w:pPr><w:r><w:t>\[end participant\]<\/w:t><\/w:r><\/w:p>