首页 > 解决方案 > 如何在 VBA 中替换 XML 文件的 unicode 字符

问题描述

问题:包含“en dash”、“em dash”的 XML 文件的目录必须替换为常规的 ASCII 字符破折号。还有单/双左/右大引号,必须用 ASCII 字符直单/双引号替换。

由于工作限制,此处只能使用基于 microsoft 的计算机上的 VBA(无法访问 powershell、脚本语言、java 等。)

我知道 VBA 可以解释 Unicode 字符,但是它不能写 unicode 字符。而不是编写 unicode 字符,而是将其替换为垃圾(即 Ite$&s,其中“e$&”是垃圾,输出应该是“It's”)

我尝试使用字符串操作的示例:

伪代码:

示例 XML:(前两个破折号分别是 en-dash 和 em-dash 在堆栈溢出时未正确显示)

<para> TEST REPLACE UNICODE CHARACTERS: — – - “ ” ‘ ’ '</para>

示例 VBA 输出:

<para> TEST REPLACE UNICODE CHARACTERS: â€&quot; â€&quot; - “ â€� ‘ ’ '</para>

代码:

Const ForReading = 1
Const TristateTrue = -1
Dim FSO As Object: Set FSO = CreateObject("Scripting.FileSystemObject")
Dim XMLString As String
XMLString = FSO.OpenTextFile(FilePath, ForReading, TristateTrue).ReadAll

UpdatedXMLString = Replace(XMLString, ChrW(8211), Chr(45))        'Replace En-Dash
UpdatedXMLString = Replace(UpdatedXMLString, ChrW(8212), Chr(45)) 'Replace Em-Dash
UpdatedXMLString = Replace(UpdatedXMLString, ChrW(8220), Chr(34)) 'Replace Left Double Curly
UpdatedXMLString = Replace(UpdatedXMLString, ChrW(8221), Chr(34)) 'Right Double Curly

Set objStream = CreateObject("ADODB.Stream")
objstream.Charset = "utf-8"
objstream.Open
objStream.WriteText UpdatedXMLString
objStream.SaveToFile UpdatedFilePath, 2

我的经验:

我知道文件中存在一个 En Dash 的事实,但是该字符的替换不成功。关于 En/Em 破折号,我不输入“If 语句”的逻辑。但是,我确实成功输入了 Curly Quotes 的“If 语句”,但字符的替换不成功。

是否必须在“FSO.OpenTextFile().ReadAll”之前执行字符替换?在 XML 文件中用 ASCII 字符替换 Unicode 字符的适当代码流是什么?

标签: xmlvbaunicodems-wordascii

解决方案


这是一个概念性的例子。

XSLT 正在使用该translate()函数。

  • 每个小写的“o”和“i”将被翻译/替换为相应的大写字母。
  • 输入 XML 还具有mdash作为实体以使其可见。它被带有常规破折号的 XSLT 取代。

对于您的情况,您需要放置自己的字符以及需要替换的字符。

输入 XML

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY mdash "&#8212;">
<!ENTITY ndash "&#8211;">
<!ELEMENT root (para)*>
<!ELEMENT para (#PCDATA)>
]>
<root>
    <para>Miami</para>
    <para>Orlando</para>
    <para>Dog &mdash; pony</para>
</root>

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="para">
        <xsl:copy>
            <xsl:value-of select="translate(., 'oi—', 'OI-')"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出 XML

<?xml version="1.0" encoding="utf-8"?>
<root>
  <para>MIamI</para>
  <para>OrlandO</para>
  <para>DOg - pOny</para>
</root>

推荐阅读