【问题标题】:How to replace XML File unicode characters in VBA如何在 VBA 中替换 XML 文件的 unicode 字符
【发布时间】:2021-10-24 00:58:34
【问题描述】:

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

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

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

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

伪代码:

  • 将 XML 内容转换为字符串
  • 如果找到 Unicode 字符“破折号”则
    • 用 ASCII 破折号/连字符替换
  • 写入 XML 文件

XML 示例:(前两个破折号分别为破折号和破折号,在堆栈溢出时未正确显示)

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

VBA 输出示例:

<para> TEST REPLACE UNICODE CHARACTERS: â€" â€" - “ â€� ‘ ’ '</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 字符的适当代码流是什么?

【问题讨论】:

  • 可能有助于显示您的完整代码,包括您如何重新保存内容。
  • 请在您的问题中添加一个最小的 XML 文件示例。 XSLT 是处理您的任务的最佳方式。
  • 你在说哪些引用,那些在 XML 中的数据中,例如内部元素或属性值?或者那些构成标记的一部分,即分隔属性值?这些输入文件是格式良好的 XML 吗?您可以使用 XSLT 1 通过 MSXML(新 MXML2.DOMDocument60)运行它们,如先前的评论中所述。
  • @TimWilliams 添加了我如何将内容输出到新文件。
  • @YitzhakKhabinsky 添加了 XML 的 sn-p

标签: xml vba unicode ms-word ascii


【解决方案1】:

这是一个概念性的例子。

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>

【讨论】:

    【解决方案2】:

    OpenTextFile 有一个 Format 参数,您可以提供该参数来设置 UTF:

    https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/opentextfile-method#:~:text=TristateTrue,file%20as%20Unicode.

    如果您不提供,则默认为 ASCII。

    另外,我认为您的原始文件可能需要保存为 UTF-16

    【讨论】:

    • 更新了代码以反映建议,但它似乎没有任何效果。不过看起来是一个简单而有前途的解决方案!
    • 源(原始)文件的编码是什么?在记事本中打开一个,然后转到另存为并检查对话框底部的格式。
    • 它是 UTF-8,但由于 XML 的目的地,它必须保持 UTF-8 @Tim Williams
    【解决方案3】:

    在此处接受使用 XSLT 的建议是一个 VBScript 示例,您应该能够将其转换为使用 MSXML 6 加载输入文档的 VBA 代码,以应用 translates 文本节点中相关字符的 XSLT 样式表并将结果写回 XML 文件:

    Set xmlDoc = CreateObject("Msxml2.DOMDocument.6.0")
    xmlDoc.preserveWhitespace = True
    
    xmlDoc.load "msxml-vb-input-sample1.xml"
    
    Set xsltDoc = CreateObject("Msxml2.DOMDocument.6.0")
    xsltDoc.load "msxml-vb-xslt-sample1.xsl"
    
    Set resultDoc = CreateObject("Msxml2.DOMDocument.6.0")
    
    xmlDoc.transformNodeToObject xsltDoc, resultDoc
    
    resultDoc.save "msxml-vb-xslt-result-sample1.xml"
    

    XSLT 就是这样做的

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        
        <xsl:param name="input-chars">—–-“”‘’'</xsl:param>
        <xsl:param name="output-chars">---""'''</xsl:param>
        
        <xsl:output encoding="UTF-8"/>
        
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
        
        <xsl:template match="text()">
            <xsl:value-of
                select="translate(., $input-chars, $output-chars)"/>
        </xsl:template>
        
    </xsl:stylesheet>
    

    然后转换例如

    <?xml version="1.0" encoding="UTF-8"?>
    <para> TEST REPLACE UNICODE CHARACTERS: — – - “ ” ‘ ’ '</para>
    

    <?xml version="1.0" encoding="UTF-8"?>
    <para> TEST REPLACE UNICODE CHARACTERS: - - - " " ' ' '</para>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-07
      • 1970-01-01
      • 1970-01-01
      • 2018-04-19
      相关资源
      最近更新 更多