使用XSLT2实现XML内容的查找与替换操作
XSLT 2.0 Solution for XML Content Find-and-Replace
Alright, let's tackle this XML content find-and-replace task using XSLT 2.0. I'll show you a clean, maintainable approach that preserves your XML structure while handling the text replacements you need.
Core Idea
We'll use the identity transform template as the foundation—this copies all your XML's existing nodes and attributes exactly as they are. Then we'll add a dedicated template to target the text you want to replace, using a centralized map for your find/replace pairs (so you can easily update entries later).
Full XSLT Implementation
Here's the complete stylesheet, tailored to your sample XML:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Identity transform: copy everything by default --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- Centralized list of find/replace pairs --> <xsl:variable name="replacements"> <entry find="2ος Όροφος" replace="Second Floor"/> <entry find="Microsoft's .NET initiative" replace="Microsoft .NET Framework"/> <!-- Add as many entries as you need here --> </xsl:variable> <!-- Template to handle text replacement in <description> elements --> <xsl:template match="description/text()"> <xsl:variable name="original" select="."/> <!-- Use XSLT 2.0's dynamic replace to match all entries at once --> <xsl:value-of select="replace( $original, string-join($replacements/entry/@find, '|'), function($match) { $replacements/entry[@find = $match]/@replace } )"/> </xsl:template> </xsl:stylesheet>
Breakdown of the Solution
- Identity Transform: This is the workhorse that keeps your XML structure intact. It copies every node and attribute unless we explicitly tell it to do something else.
- Replacement Map: The
$replacementsvariable holds all your find/replace pairs. No need to mess with the logic later—just add or edit entries here. - Text Replacement Template: This targets text inside
<description>elements. Using XSLT 2.0'sreplace()function with a dynamic lookup, we match any of your find strings and swap them with their corresponding replacement values in one pass.
Test with Your Sample Input
For your provided XML snippet:
<TABLE NAME="TEST"> <DATA RECORDS="78"> <catalog> <book id="bk109"> <description>2ος Όροφος</description> </book> <book id="bk110"> <description>Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</description> </book> </catalog> </DATA> </TABLE>
The output will be:
<TABLE NAME="TEST"> <DATA RECORDS="78"> <catalog> <book id="bk109"> <description>Second Floor</description> </book> <book id="bk110"> <description>Microsoft .NET Framework is explored in detail in this deep programmer's reference.</description> </book> </catalog> </DATA> </TABLE>
Quick Customization Tips
- Target More Elements: If you need replacements in other elements (like
<title>), adjust the match pattern tomatch="title/text()"or evenmatch="text()"to apply to all text nodes. - Case-Insensitive Matching: Add the
iflag to thereplace()function:replace($original, string-join(...), ..., 'i'). - Escape Regex Special Characters: If your find strings have characters like
.,*, or+, use a helper function to escape them (sincereplace()uses regex under the hood).
内容的提问来源于stack exchange,提问作者user8558474
相关产品推荐
相关产品推荐

