替换各种XML文件中的字符串 [英] Replacing strings in various XML files
问题描述
给出以下xml文件,其结构和内容可以更改:
Given the following xml file with the knowledge that the structure and contents can change:
<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".因此结果将是:
I would like a way to use xquery (and even xslt) to replace all instances of a supplied string with another. For example, replace the word "Bird" with "Dog". Therefore the results would be:
<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 ),但这是针对文本的,不是整个文档.
I have no idea if this is even possible. Every attempt I have made has eliminated the tags. I have even tried this example (http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx), but it is for text not an entire document.
请帮助!
更新
我尝试使用xslt 2.0建议运行,因为它似乎最合适.在尝试针对我的情况进行修改时,我一直保持干爽状态.
I tried running with the xslt 2.0 suggestion as it seemed to fit the best. While attempting to modify it for my case, I keep coming up dry.
我想传递一个xml参数来定义替换项.因此,像这样修改xslt:
I want to pass in an xml parameter to define the replacements. So, modifying the xslt like this:
<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>
不用说,但是,我不希望它重复并且也不正确.
Needless to say, but, I don't want it duplicated and also incorrect.
请帮助!
推荐答案
如果同时选择XQuery和XSLT,则可能使用XSLT 2.0处理器.如果是这样,这应该可行:
If both XQuery and XSLT are an option, you're probably using an XSLT 2.0 processor. If so, this should work:
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>
使用问题的XML输入,此XSLT产生以下输出:
Using the XML input from the question, this XSLT produces the following output:
<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>
注意:在创建输出时,不会更改任何元素/属性/注释/处理指令.
Note: No elements/attributes/comments/processing-instructions would be altered in the creation of the output.
编辑
获取重复项的原因是因为您的xsl:for-each
遍历了两个word
元素.如果您有3个,它将输出3次文本.
The reason you're getting duplicates is because your xsl:for-each
is looping over the two word
elements. If you had 3, it would output the text 3 times.
您只需要以不同的方式构建正则表达式即可:
You just need to build the regex a little differently:
<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>
这篇关于替换各种XML文件中的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!