替换各种XML文件中的字符串 [英] Replacing strings in various XML files

查看:128
本文介绍了替换各种XML文件中的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆