将 non-ascii 个字符写入 xml/UTF-8

Writing non-ascii characters to xml/UTF-8

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

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

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

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

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

编辑 2:需要说明的是:我认为正在发生的事情是 non-ascii 字符以 UTF-8 以外的其他方式编码,这导致我的 XML 输出无效.如何让 applescript 或 JXA 将 non-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 中,您将使用 write theText to theFile as «class utf8» 来编写 UTF8 编码的文本。您不能在 JXA 中执行此操作,因为无法编写原始 AE 代码。

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

如果您必须使用 JXA,唯一的解决方法是通过 Cocoa API 编写您的 UTF8 文件。尽管通过字符串混合生成 XML 是邪恶的并且容易出错,所以您可能会借此机会重写代码以使用正确的 XML API。 (再次强调,对于 Node,您的选择太多了,最困难的部分将是确定哪些 NPM 库健壮且易于使用,哪些是垃圾。使用 AS/JXA,它要么是系统事件的 XML 套件,这很慢,或者 Cocoa 的 XML API 很复杂。)