给出以下xml文件,知道结构和内容可以更改:
<something> <parent> <child>Bird is the word 1.</child> <child>Curd is the word 2.</child> <child>Nerd is the word 3.</child> </parent> <parent> <child>Bird is the word 4.</child> <child>Word is the word 5.</child> <child>Bird is the word 6.</child> </parent> </something>
我想用一种方法来使用xquery(甚至xslt)来替换所提供的字符串的所有实例.例如,将“Bird”替换为“Dog”.因此结果将是:
<something> <parent> <child>Dog is the word 1.</child> <child>Curd is the word 2.</child> <child>Nerd is the word 3.</child> </parent> <parent> <child>Dog is the word 4.</child> <child>Word is the word 5.</child> <child>Dog is the word 6.</child> </parent> </something>
我不知道这是否可能.我所做的每一次尝试都消除了标签.我甚至尝试了这个例子(http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx),但它是用于文本而不是整个文档.
请帮忙!
UPDATE
我尝试使用xslt 2.0建议,因为它似乎最合适.在尝试根据我的情况修改它时,我一直在干涸.
我想传入一个xml参数来定义替换.所以,像这样修改xslt:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="list"> <words> <word> <search>Bird</search> <replace>Dog</replace> </word> <word> <search>word</search> <replace>man</replace> </word> </words> </xsl:param> <xsl:template match="@*|*|comment()|processing-instruction()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="text()"> <xsl:param name="chosen" select="." /> <xsl:for-each select="$list//word"> <xsl:variable name="search"><xsl:value-of select="search" /></xsl:variable> <xsl:analyze-string select="$chosen" regex="{$search}"> <xsl:matching-substring><xsl:value-of select="replace" /></xsl:matching-substring> <xsl:non-matching-substring><xsl:value-of select="$chosen"/></xsl:non-matching-substring> </xsl:analyze-string> </xsl:for-each> </xsl:template> </xsl:stylesheet>
结果是:
<something> <parent> <child>Bird is the word 1.Bird is the word 1.</child> <child>Curd is the word 2.Curd is the word 2.</child> <child>Nerd is the word 3.Nerd is the word 3.</child> </parent> <parent> <child>Bird is the word 4.Bird is the word 4.</child> <child>Word is the word 5.Word is the word 5.</child> <child>Bird is the word 6.Bird is the word 6.</child> </parent> </something>
不用说,但是,我不希望它重复,也不正确.
请帮忙!
如果XQuery和XSLT都是一个选项,那么你可能正在使用XSLT 2.0处理器.如果是这样,这应该工作:
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="search" select="'Bird'"/> <xsl:param name="replace" select="'Dog'"/> <xsl:template match="@*|*|comment()|processing-instruction()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="text()"> <xsl:analyze-string select="." regex="{$search}"> <xsl:matching-substring><xsl:value-of select="$replace"/></xsl:matching-substring> <xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring> </xsl:analyze-string> </xsl:template> </xsl:stylesheet>
<something> <parent> <child>Dog is the word 1.</child> <child>Curd is the word 2.</child> <child>Nerd is the word 3.</child> </parent> <parent> <child>Dog is the word 4.</child> <child>Word is the word 5.</child> <child>Dog is the word 6.</child> </parent> </something>
编辑
你得到重复的原因是你的xsl:for-each循环遍历两个单词元素.如果你有3,它将输出文本3次.
你只需要以不同的方式构建正则表达式:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="list"> <words> <word> <search>Bird</search> <replace>Dog</replace> </word> <word> <search>word</search> <replace>man</replace> </word> </words> </xsl:param> <xsl:template match="@*|*|comment()|processing-instruction()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="text()"> <xsl:variable name="search" select="concat('(',string-join($list/words/word/search,'|'),')')"/> <xsl:analyze-string select="." regex="{$search}"> <xsl:matching-substring> <xsl:value-of select="$list/words/word[search=current()]/replace"/> </xsl:matching-substring> <xsl:non-matching-substring> <xsl:value-of select="."/> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:template> </xsl:stylesheet>
这将产生:
<something> <parent> <child>Dog is the man 1.</child> <child>Curd is the man 2.</child> <child>Nerd is the man 3.</child> </parent> <parent> <child>Dog is the man 4.</child> <child>Word is the man 5.</child> <child>Dog is the man 6.</child> </parent> </something>