替换xml的属性值中的特殊字符

时间:2016-04-11 20:21:07

标签: xml sql-server-2008 replace xquery-sql

我需要更新表中的xml列以删除特定节点的评级Ratingtype =“unknown”的特殊字符(%)。除上述节点之外的节点中存在的特殊字符不应更改。以下是我的输入和期望的结果。

            Input xml:
            <Ratings>
              <Rating Ratingtype="unknown">
                <AppliedKnowledge value="Yes%">3.0</AppliedKnowledge>
                <ToolSkills>3.5</ToolSkills>
              </Rating>
              <Rating Ratingtype="known">
              <AppliedKnowledge value="%Yes%">3.0</AppliedKnowledge>
                <Experience>9.5</Experience>
                <Education>16.0</Education>
                <DbDevelopment>4.5</DbDevelopment>
              </Rating>
              <Rating Ratingtype="unknown">
                <AppliedKnowledge value="%No%">4.0</AppliedKnowledge>
                <ToolSkills>4.5</ToolSkills>
              </Rating>
            </Ratings>

            Expected output xml:
            <Ratings>
              <Rating Ratingtype="unknown">
                <AppliedKnowledge value="Yes">3.0</AppliedKnowledge>
                <ToolSkills>3.5</ToolSkills>
              </Rating>
              <Rating Ratingtype="known">
              <AppliedKnowledge value="%Yes%">3.0</AppliedKnowledge>
                <Experience>9.5</Experience>
                <Education>16.0</Education>
                <DbDevelopment>4.5</DbDevelopment>
              </Rating>
              <Rating Ratingtype="unknown">
                <AppliedKnowledge value="No">4.0</AppliedKnowledge>
                <ToolSkills>4.5</ToolSkills>
              </Rating>
            </Ratings>

1 个答案:

答案 0 :(得分:1)

与您的上一个问题相似,不容易。

" set the runtime path to include Vundle and initialize set rtp+=~/.vim/bundle/Vundle.vim call vundle#begin() " alternatively, pass a path where Vundle should install plugins "call vundle#begin('~/some/path/here') "plugin to switch easily between header and source Plugin 'derekwyatt/vim-fswitch' " All of your Plugins must be added before the following line call vundle#end() " required .... 方法允许每次调用一次更改。这意味着您必须使用某种循环。

仍然有方法:

如果.modify()未在其他地方使用,您可以直接执行此操作:

将XML转换为%,执行简单的文本替换并将其转换回来

VARCHAR

比循环更好

将XML撕碎并再次构建它。仅对目标值使用SELECT CAST(REPLACE(CAST(@YourXml AS VARCHAR(MAX)),'%','') AS XML)

REPLACE

结果

DECLARE @x XML=
'<Ratings>
  <Rating Ratingtype="unknown">
    <AppliedKnowledge value="Yes%">3.0</AppliedKnowledge>
    <ToolSkills>3.5</ToolSkills>
  </Rating>
  <Rating Ratingtype="known">
    <AppliedKnowledge value="%Yes%">3.0</AppliedKnowledge>
    <Experience>9.5</Experience>
    <Education>16.0</Education>
    <DbDevelopment>4.5</DbDevelopment>
  </Rating>
  <Rating Ratingtype="unknown">
    <AppliedKnowledge value="%No%">4.0</AppliedKnowledge>
    <ToolSkills>4.5</ToolSkills>
  </Rating>
</Ratings>';

SELECT CAST(REPLACE(CAST(@x AS VARCHAR(MAX)),'%','')  AS XML)

SELECT R.value('@Ratingtype','varchar(max)') AS [@Ratingtype]
      ,CASE WHEN R.value('@Ratingtype','varchar(max)')='unknown'
            THEN REPLACE(R.value('(AppliedKnowledge/@value)[1]','varchar(max)'),'%','')
            ELSE R.value('(AppliedKnowledge/@value)[1]','varchar(max)') END AS [AppliedKnowledge/@Value]
      ,R.value('AppliedKnowledge[1]','varchar(max)') AS [AppliedKnowledge]
      ,R.value('ToolSkills[1]','varchar(max)') AS [ToolSkills]
      ,R.value('Experience[1]','varchar(max)') AS [Experience]
      ,R.value('Education[1]','varchar(max)') AS [Education]
      ,R.value('DbDevelopment[1]','varchar(max)') AS [DbDevelopment]
FROM @x.nodes('/Ratings/Rating') AS A(R)
FOR XML PATH('Rating'),ROOT('Ratings')