问题
Input:
<xsl:variable name="nodelist">
<root>
<a size="12" number="11">
<sex>male</sex>
Jens
</a>
<a size="12" number="11">
<sex>male</sex>
Hulk
</a>
<a size="12" number="11">
<sex>male</sex>
Steven XXXXXXXXXXX
</a>
<a size="12" number="11">
<sex>male</sex>
Joschua
</a>
<a size="12" number="11">
<sex>female</sex>
Angelina
</a>
</root>
</variable>
Desired output:
<root>
<a size="12" number="11">
<sex>male</sex>
Jens
</a>
<a size="12" number="11">
<sex>male</sex>
Hulk
</a>
<a size="12" number="11">
<sex>male</sex>
Steven YYYYYYYYYYYY
</a>
<a size="12" number="11">
<sex>male</sex>
Joschua
</a>
<a size="12" number="11">
<sex>female</sex>
Angelina
</a>
</root>
I want to change the a node with XXXXXXXXXXX. Can I copy the first and last two nodes, change the third and then put back together again like this. (XLST 1.0)
<xsl:variable name="begin">
<xsl:value-of select="substring-before($nodelist, 'XXXXXXXXXXX')"/>
</xsl:variable>
<xsl:variable name="replaceString">
YYYYYYYYYYYY
</xsl:variable>
<xsl:variable name="end">
<xsl:value-of select="substring-after($nodelist, 'xxxxx')"/>
</xsl:variable>
<xsl:variable name="all">
<xsl:copy-of select="$begin"/>
<xsl:copy-of select="$replaceString"/>
<xsl:copy-of select="$end"/>
</xsl:variable>
With substring i have lost all information about the nodes. This is the result with substring
<root>
male Jens
male Hulk
male Steven YYYYYYYYYYYY
male Joschua
female Angelina
</root>
回答1:
You need to make your stylesheet a bit more targeted. Changing only the text()
that contains the value that needs to be replaced. For everything else, the identity template will ensure that the content is copied:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<!--Identity template will copy all matched nodes and apply-templates-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--Specialized template to match on text nodes that contain the "findString" value-->
<xsl:template match="text()[contains(.,'XXXXXXXXXXX')]">
<xsl:variable name="findString" select="'XXXXXXXXXXX'"/>
<xsl:variable name="replaceString" select="'YYYYYYYYYYYY'"/>
<xsl:value-of select="concat(substring-before(., $findString),
$replaceString,
substring-after(., $findString))"/>
</xsl:template>
</xsl:stylesheet>
来源:https://stackoverflow.com/questions/16126641/xslt-copy-nodes-and-modify-them