【问题标题】:Writing non-ascii characters to xml/UTF-8将非 ascii 字符写入 xml/UTF-8
【发布时间】:2020-05-19 08:28:47
【问题描述】:

我有一个脚本,它通过字符串操作(我在发现 XML 套件之前编写的)组装一个 xml 文档。

当包含某些字符时,例如 £、–(en-dash) 和 —(em dash)(我怀疑所有非 ascii 字符),它们将被替换为 unicode 替换字符(U+FFFD)

在文档开头有 xml 标头时发生:即<?xml。对此进行任何更改都可以解决问题并将我期望的内容写入文件。我的假设是applescript试图将字符串解析为xml,但我希望它作为字符串传递。

我正在使用 JXA 编写,但包含了 Applescript 等价物,因为我认为问题出在 OSA 并且可能有更多的 Applescript 用户!

编辑:好的,我猜这更像是一个编码问题 - 读取为 UTF-8(我生成的 xml 应该是)会导致替换字符,但 Western 或 Mac Roman 正确显示字符。不过 UTF-8 肯定支持这些字符,所以我不确定前进的最佳方式是什么?

编辑 2:为了清楚起见:我认为正在发生的事情是非 ascii 字符被编码为 UTF-8 以外的东西,这导致我的 XML 输出无效。如何让 applescript 或 JXA 将非 ascii 字符编码为 UTF-8?

Applescript

set dt to path to desktop as text
set filePath to dt & "test1.txt"

writeTextToFile(text1, filePath, true)

-- using the example handler from the Mac Automation Scripting Guide
on writeTextToFile(theText, theFile, overwriteExistingContent)
    try

        -- Convert the file to a string
        set theFile to theFile as string

        -- Open the file for writing
        set theOpenedFile to open for access file theFile with write permission

        -- Clear the file if content should be overwritten
        if overwriteExistingContent is true then set eof of theOpenedFile to 0

        -- Write the new content to the file
        write theText to theOpenedFile starting at eof

        -- Close the file
        close access theOpenedFile

        -- Return a boolean indicating that writing was successful
        return true

        -- Handle a write error
    on error

        -- Close the file
        try
            close access file theFile
        end try

        -- Return a boolean indicating that writing failed
        return false
    end try
end writeTextToFile

自动化Javascript

app.includeStandardAdditions = true

function writeTextToFile(text, file, overwriteExistingContent) {
    try {

        // Convert the file to a string
        var fileString = file.toString()

        // Open the file for writing
        var openedFile = app.openForAccess(Path(fileString), { writePermission: true })

        // Clear the file if content should be overwritten
        if (overwriteExistingContent) {
            app.setEof(openedFile, { to: 0 })
        }

        // Write the new content to the file
        app.write(text, { to: openedFile, startingAt: app.getEof(openedFile) })

        // Close the file
        app.closeAccess(openedFile)

        // Return a boolean indicating that writing was successful
        return true
    }
    catch(error) {

        try {
            // Close the file
            app.closeAccess(file)
        }
        catch(error) {
            // Report the error is closing failed
            console.log(`Couldn't close file: ${error}`)
        }

        // Return a boolean indicating that writing was successful
        return false
    }
}

var text = "<?xml £"
var file = Path("Users/benfrearson/Desktop/text.txt")


writeTextToFile (text, file, true)

【问题讨论】:

  • 鉴于您的 AppleScript 代码,应该为text1 变量分配什么值来重现您的问题?是不是应该是 set text1 to "&lt;?xml £" ?因为当我添加那行代码并运行您的 AppleScript 时,它会将一个名为 test1.txt 的新文件写入 Desktop。如果我然后打开该结果文件,例如TextEdit 它有以下内容:&lt;?xml £ - 你是说这不是发生在你身上的事情,而是内容是 unicode?​​span>
  • 哎呀,是的!看起来我错过了顶线!当我明确打开它(在 Atom 中)并将编码设置为 UTF-8 时,它不显示 £ 字符。

标签: xml applescript javascript-automation


【解决方案1】:

在 AppleScript 中,您可以使用 write theText to theFile as «class utf8» 来编写 UTF8 编码的文本。你不能在 JXA 中这样做,因为无法编写原始 AE 代码。

我通常建议不要使用 JXA,因为它 1. 有缺陷和残废,以及 2. 被遗弃。如果您总体上喜欢 JavaScript,那么使用 Node.js 会好得多。对于应用程序自动化,您最好坚持使用 AppleScript:虽然它是一门蹩脚的语言,而且垂死挣扎,但至少它正确地讲述了 Apple 活动,并且提供了一半体面的文档和社区支持。

如果您必须使用 JXA,唯一的解决方法是改为通过 Cocoa API 编写 UTF8 文件。尽管无论如何通过字符串混搭生成 XML 是邪恶的并且容易出错,因此您可能最好借此机会重写您的代码以使用适当的 XML API。 (同样,对于 Node,您会被宠坏,最困难的部分将是确定哪些 NPM 库是健壮且易于使用的,哪些是垃圾。对于 AS/JXA,它要么是系统事件的 XML 套件,它很慢,要么Cocoa 的 XML API,很复杂。)

【讨论】:

  • 是的,这回答了问题!在 Applescript 中工作,在纯 JXA 中没有机会。我找到了更多信息 here 我选择了 JXA,因为我需要进行额外的字符串操作,而 applescript 对此非常迟钝。明确一点:我正在做的是读取 XML 模板文件,然后用文本文件中的值替换占位符字符串。将来使用 XML API 可能会更好(但现在它很可靠)
猜你喜欢
  • 2014-04-06
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
  • 2013-11-17
  • 2021-10-27
  • 1970-01-01
相关资源
最近更新 更多