Wrapping all nodes in between 2 Processing Instructions with XSLT

ぐ巨炮叔叔 提交于 2021-01-29 07:16:51

问题


Input XML:

<content>
<p>
<?start?>
test 
<em>
test man
</em>
<strong>test man</strong>
<?end?>
do not grab this text
<strong>or this text</strong>
</p>
</content>

Desired output XML:

<content>
<p>
<ins>
  test 
  <em>
  test man
  </em>
  <strong>test man</strong>
</ins>
do not grab this text
<strong>or this text</strong>
</p>
</content>

I'm trying to wrap all text nodes and nodes in between the two processing instructions in a tag. Is there any way to achieve this with XSLT 2.0?

My current template that is not working:

  <xsl:variable name="pi-end" select="processing-instruction('end')" />

       <xsl:template match="processing-instruction('start')">
             <ins>
                <xsl:apply-templates mode="copy" select="following-sibling::node()[. &lt;&lt;  $pi-end]"/>
             </ins>
        </xsl:template> 

Is there a way to achieve this by designing a template that matches on the PI and grabs all the following nodes until the end PI? I need the flexibility as these PI's could be anywhere in the data and inside of any tag.


回答1:


Use this

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


    <xsl:output indent="yes" method="xml"/>

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="processing-instruction('start')">
        <xsl:variable name="piend"
            select="following-sibling::processing-instruction('end')[1]/generate-id()"/>
        <ins>
            <xsl:copy-of
                select="following-sibling::node()[following-sibling::processing-instruction('end')[generate-id() = $piend]]"
            />
        </ins>
    </xsl:template>

    <xsl:template
        match="node()[preceding::processing-instruction()[1][self::processing-instruction('start')]][following::processing-instruction()[1][self::processing-instruction('end')]]"> </xsl:template>
    
    <xsl:template match="processing-instruction('end')">
        
    </xsl:template>
</xsl:stylesheet>

See transformation at https://xsltfiddle.liberty-development.net/93dFKa8



来源:https://stackoverflow.com/questions/63909389/wrapping-all-nodes-in-between-2-processing-instructions-with-xslt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!