问题
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()[. << $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