草庐IT

xml - XSLT + 用转义序列替换双引号

coder 2024-06-23 原文

我有以下 xslt 将数据转换为 JQuery 可接受的格式。但是,因为 JSON 不接受数据字符串中的双引号,所以我需要将 "替换为转义序列\"

XML:

<?xml version="1.0" encoding="UTF-8"?>
<Rowsets>
    <Rowset>
        <Columns>
            <Column Description="Element_1" SQLDataType="12" />
            <Column Description="Element_2" SQLDataType="12" />
            <Column Description="Element_3" SQLDataType="93" />
        </Columns>
        <Row>
            <Element_1>test_data</Element_1>
            <Element_2>test_quo"te</Element_2>
            <Element_3>test_data</Element_3>
        </Row>
    </Rowset>
</Rowsets>

当前的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" exclude-result-prefixes="java">
    <xsl:output method="text" media-type="text/csv" encoding="UTF-8"/>
    <xsl:param name="RowDelim">],</xsl:param>
    <xsl:param name="RowLast">]</xsl:param>
    <xsl:param name="RowStart">[</xsl:param>
    <xsl:param name="startBracket">{ </xsl:param>
    <xsl:param name="JQTableData">"aaData": [</xsl:param>
    <xsl:param name="JQTableEnd">] }</xsl:param>
    <xsl:param name="FieldDelim">,</xsl:param>
    <xsl:param name="StringDelim">"</xsl:param>
    <xsl:param name="DateFormat">yyyy-MM-dd HH:mm:ss</xsl:param>


    <xsl:template match="/">





        <xsl:for-each select="Rowsets">

            <xsl:for-each select="Rowset">
            <xsl:value-of select="$startBracket"/>
            <xsl:value-of select="$JQTableData"/>
                <xsl:variable name="CurrentColumns" select="Columns"/>
                <xsl:for-each select="Columns">
                    <xsl:for-each select="Column">

                        <xsl:if test="not(position() = last())">

                        </xsl:if>
                    </xsl:for-each>

                </xsl:for-each>
                <xsl:for-each select="Row">
                <xsl:value-of select="$RowStart"/>
                    <xsl:for-each select="*">
                        <xsl:variable name="ColName">
                            <xsl:value-of select="name(.)"/>
                        </xsl:variable>
                        <xsl:variable name="ColType">
                            <xsl:value-of select="$CurrentColumns/Column[@Name=$ColName]/@SQLDataType"/>
                        </xsl:variable>
                        <xsl:choose>
                            <xsl:when test="$ColType= '2' or $ColType= '3' or $ColType= '4' or $ColType= '5' or 

$ColType= '6' or $ColType= '7' or $ColType= '8' or $ColType= '-7'">
                                <xsl:value-of select="."/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="$StringDelim"/>
                                <xsl:choose>
                                    <xsl:when test="$ColType= '91' or $ColType= '92' or $ColType= '93'">
                                        <xsl:choose>
                                            <xsl:when test=". = 'TimeUnavailable'">
                                                <xsl:value-of select="."/>
                                            </xsl:when>
                                            <xsl:otherwise>
                                                                                        </xsl:otherwise>
                                        </xsl:choose>
                                    </xsl:when>
                                    <xsl:otherwise>
                                    <xsl:choose>
                                        <xsl:when test=". = 'true'">
                                            <xsl:text>Y</xsl:text>
                                        </xsl:when>
                                        <xsl:when test=". = 'false'">
                                            <xsl:text>N</xsl:text>
                                        </xsl:when>
                                        <xsl:otherwise>
                                            <xsl:value-of select="."/>
                                        </xsl:otherwise>
                                        </xsl:choose>
                                    </xsl:otherwise>
                                </xsl:choose>
                                <xsl:value-of select="$StringDelim"/>
                            </xsl:otherwise>
                        </xsl:choose>
                        <xsl:if test="not(position() = last())">
                            <xsl:value-of select="$FieldDelim"/>
                        </xsl:if>
                    </xsl:for-each>
                            <xsl:if test="not(position() = last())">
                            <xsl:value-of select="$RowDelim"/>
                        </xsl:if>
                            <xsl:if test="position() = last()">
                            <xsl:value-of select="$RowLast"/>
                        </xsl:if>

                </xsl:for-each>
                <xsl:value-of select="$JQTableEnd"/>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>



</xsl:stylesheet>

当前输出:

{ "aaData": [["test_data","test_quo"te","test_data"]] }

期望的输出:

{ "aaData": [["test_data","test_quo\"te","test_data"]] }

最佳答案

将此模板添加到您的代码中:

    <xsl:template name="escapeQuote">
      <xsl:param name="pText" select="."/>

      <xsl:if test="string-length($pText) >0">
       <xsl:value-of select=
        "substring-before(concat($pText, '&quot;'), '&quot;')"/>

       <xsl:if test="contains($pText, '&quot;')">
        <xsl:text>\"</xsl:text>

        <xsl:call-template name="escapeQuote">
          <xsl:with-param name="pText" select=
          "substring-after($pText, '&quot;')"/>
        </xsl:call-template>
       </xsl:if>
      </xsl:if>
    </xsl:template>

然后改变:

<xsl:value-of select="."/>

:

<xsl:call-template name="escapeQuote"/>

您的完整转变现在变成了:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" exclude-result-prefixes="java">
        <xsl:output method="text" media-type="text/csv" encoding="UTF-8"/>
        <xsl:param name="RowDelim">],</xsl:param>
        <xsl:param name="RowLast">]</xsl:param>
        <xsl:param name="RowStart">[</xsl:param>
        <xsl:param name="startBracket">{ </xsl:param>
        <xsl:param name="JQTableData">"aaData": [</xsl:param>
        <xsl:param name="JQTableEnd">] }</xsl:param>
        <xsl:param name="FieldDelim">,</xsl:param>
        <xsl:param name="StringDelim">"</xsl:param>
        <xsl:param name="DateFormat">yyyy-MM-dd HH:mm:ss</xsl:param>


        <xsl:template match="/">

            <xsl:for-each select="Rowsets">

                <xsl:for-each select="Rowset">
                <xsl:value-of select="$startBracket"/>
                <xsl:value-of select="$JQTableData"/>
                    <xsl:variable name="CurrentColumns" select="Columns"/>
                    <xsl:for-each select="Columns">
                        <xsl:for-each select="Column">

                            <xsl:if test="not(position() = last())">

                            </xsl:if>
                        </xsl:for-each>

                    </xsl:for-each>
                    <xsl:for-each select="Row">
                    <xsl:value-of select="$RowStart"/>
                        <xsl:for-each select="*">
                            <xsl:variable name="ColName">
                                <xsl:value-of select="name(.)"/>
                            </xsl:variable>
                            <xsl:variable name="ColType">
                                <xsl:value-of select="$CurrentColumns/Column[@Name=$ColName]/@SQLDataType"/>
                            </xsl:variable>
                            <xsl:choose>
                                <xsl:when test="$ColType= '2' or $ColType= '3' or $ColType= '4' or $ColType= '5' or

    $ColType= '6' or $ColType= '7' or $ColType= '8' or $ColType= '-7'">
                                    <xsl:value-of select="."/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="$StringDelim"/>
                                    <xsl:choose>
                                        <xsl:when test="$ColType= '91' or $ColType= '92' or $ColType= '93'">
                                            <xsl:choose>
                                                <xsl:when test=". = 'TimeUnavailable'">
                                                    <xsl:value-of select="."/>
                                                </xsl:when>
                                                <xsl:otherwise>
                                                                                            </xsl:otherwise>
                                            </xsl:choose>
                                        </xsl:when>
                                        <xsl:otherwise>
                                        <xsl:choose>
                                            <xsl:when test=". = 'true'">
                                                <xsl:text>Y</xsl:text>
                                            </xsl:when>
                                            <xsl:when test=". = 'false'">
                                                <xsl:text>N</xsl:text>
                                            </xsl:when>
                                            <xsl:otherwise>
                                              <xsl:call-template name="escapeQuote"/>
                                                <!-- <xsl:value-of select="."/> -->
                                            </xsl:otherwise>
                                            </xsl:choose>
                                        </xsl:otherwise>
                                    </xsl:choose>
                                    <xsl:value-of select="$StringDelim"/>
                                </xsl:otherwise>
                            </xsl:choose>
                            <xsl:if test="not(position() = last())">
                                <xsl:value-of select="$FieldDelim"/>
                            </xsl:if>
                        </xsl:for-each>
                                <xsl:if test="not(position() = last())">
                                <xsl:value-of select="$RowDelim"/>
                            </xsl:if>
                                <xsl:if test="position() = last()">
                                <xsl:value-of select="$RowLast"/>
                            </xsl:if>

                    </xsl:for-each>
                    <xsl:value-of select="$JQTableEnd"/>
                </xsl:for-each>
            </xsl:for-each>
        </xsl:template>

        <xsl:template name="escapeQuote">
          <xsl:param name="pText" select="."/>

          <xsl:if test="string-length($pText) >0">
           <xsl:value-of select=
            "substring-before(concat($pText, '&quot;'), '&quot;')"/>

           <xsl:if test="contains($pText, '&quot;')">
            <xsl:text>\"</xsl:text>

            <xsl:call-template name="escapeQuote">
              <xsl:with-param name="pText" select=
              "substring-after($pText, '&quot;')"/>
            </xsl:call-template>
           </xsl:if>
          </xsl:if>
        </xsl:template>

</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<Rowsets>
    <Rowset>
        <Columns>
            <Column Description="Element_1" SQLDataType="12" />
            <Column Description="Element_2" SQLDataType="12" />
            <Column Description="Element_3" SQLDataType="93" />
        </Columns>
        <Row>
            <Element_1>test_data</Element_1>
            <Element_2>test_quo"te</Element_2>
            <Element_3>test_data</Element_3>
        </Row>
    </Rowset>
</Rowsets>

产生了想要的、正确的结果:

{ "aaData": [["test_data","test_quo\"te","test_data"]] }

关于xml - XSLT + 用转义序列替换双引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9370633/

有关xml - XSLT + 用转义序列替换双引号的更多相关文章

  1. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  5. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  6. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  7. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  8. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  9. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  10. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

随机推荐