> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kasoftware.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ArcScript 简介

> ArcScript 语言的核心概念，包括对象、对象集、运算器、关键字和内置脚本对象，并提供示例脚本。

export const siteNameShort = "知行之桥";

export const siteName = "知行之桥";

{siteNameShort}Script 是 {siteName} 中内置的一种基于 XML 的语言，可用于编写自定义处理逻辑。{siteNameShort}Script 可以轻松转换文件或消息，并与其它业务流程集成。{siteNameShort} 包含完整的[示例脚本](#示例脚本)，用于发送电子邮件、执行批处理文件、处理文件等。您可以从管理控制台将这些示例插入到脚本和事件中。

不过，{siteNameShort}Script 也是一种高级编程语言，能够控制数据访问和处理的几乎每一个方面。您可以使用[关键字](./keyword-reference/keywords)、属性、对象、[运算器](./operations/operations)和对象集来编写脚本，并在所有端口的[事件](./scripting#event-scripting)、专用 [Script](../connectors/script) 和 [REST](../connectors/rest) 端口，以及 [XML Map 端口](../connectors/xml-map/xml-map)的[自定义脚本](../connectors/xml-map/xml-map-advanced#custom-scripts)选项中使用这些脚本。

* **属性**：名称-值对中的名称部分，例如 attribute="address"、value="123 Pleasant Lane"。
  * 使用 `#` 字符表示属性是数组。这表示数组可以包含多个值，每个值都可以使用从 1 开始的索引来引用。
  * 例如，`[myitem.myattribute#2]` 指向 `myattribute` 属性的第二个值。

* **对象**：描述输入或输出的一组相关属性-值对。例如：

  ```
  Attribute="name" value="Bob"
  Attribute="address" value="123 Pleasant Lane"
  Attribute="phone" value="123-4567"
  ```

* **对象集**：对象的列表，例如包含客户地址和电话号码的客户列表。

* **运算器**：接受对象作为输入并生成对象集作为输出的方法的通用名称。

* **关键字**：{siteNameShort}Script 语句，例如 [arc:set](./keyword-reference/op-arc-set)。

<Note>{siteNameShort}Script 中的数组限制为 32768 个成员。</Note>

{siteNameShort}Script 包含许多关键字，可用于执行以下操作：

* 描述脚本输入和输出
* 使用 if/else 语句和 case 语句等高级编程结构控制执行流程
* 调用运算器并定义自己的运算器
* 创建和修改用作运算器输入的对象，以及对象集（运算器的输出）
* 通过迭代对象集中的对象来处理运算器调用产生的对象集

## 示例脚本

{siteNameShort} 包含用于自动化常见操作（如发送电子邮件）的完整代码片段。在 [Script 端口的设置选项卡](../connectors/script#settings-tab)或任意端口的**事件**选项卡上，单击**插入片段**，然后选择要执行的操作。必要的代码会插入到光标处。

以下部分介绍如何使用和扩展这些代码片段来编写自定义处理逻辑。

### 使用事件输入

每个事件都提供相关输入，可将其用作运算器的输入参数。输入参数由 info 部分中的 input 属性定义。

使用事件的预定义输入可以处理已发送或已接收的文件，或发送包含任何错误消息的电子邮件。还可以使用其它输入。例如，**After Receive** 事件的可用输入如下：

```xml theme={null}
<arc:info title="After Receive" desc="This event is fired after receiving a file.">
  <input name="WorkspaceId"      desc="The id of the workspace that is receiving file." />
  <input name="ConnectorId"      desc="The id of the connector that is receiving file." />
  <input name="Direction"        desc="The direction of transaction." />
  <input name="Filename"         desc="The name of the file that was received." />
  <input name="FilePath"         desc="The path of the file that was received." />
  <input name="Attachment#"      desc="The path of the attachment was received." />
  <input name="MessageId"        desc="The Id of the transaction." />
  <input name="ErrorMessage"     desc="If an error occurred, this will contain the error message." />
</arc:info>
```

### 使用运算器

使用内含的代码示例可以调用一些内置[运算器](./operations/operations)。下面的示例使用 [appSendEmail](./operations/op-app-send-email) 运算器在收到文件后发送电子邮件。要使用它，只需替换占位符值：

```xml theme={null}
<!-- Send Email -->
<arc:set attr="email.To"         value="Recipient(s)"/>
<arc:set attr="email.Subject"    value="Before Send"/>
<arc:set attr="email.Message"    value="File [Filename] was processed."/>
<arc:call op="appSendEmail"/>
```

<Note>仅当您此前已在**设置**（单击齿轮图标访问）中配置了邮件服务器时，上面显示的脚本才有效。导航到[提醒选项卡](../getting-started/administration/settings/alerts)的**电子邮件设置**部分。appSendEmail 运算器使用同一邮件服务器。</Note>

### 扩展示例脚本

使用内含的代码示例可以将预定义输入传递给[运算器](./operations/operations)。您还可以传入特定于运算器的输入。例如，[appSendEmail](./operations/op-app-send-email) 运算器接受正文文本和附件等多个附加输入。使用 [arc:set](./keyword-reference/op-arc-set) 关键字提供这些值。

使用 [arc:call](./keyword-reference/op-arc-call) 关键字可以调用事件中的任何内置运算器，或调用 API。

使用其它关键字可以控制执行流程等。{siteNameShort}Script 在计算上是完备的，并包含多种增强功能，旨在让处理和自动化更简单。有关 {siteNameShort}Script 语法及其功能的更多信息，请参阅[脚本](./scripting)。

## {siteNameShort}Script 中的对象

对象集由*对象*组成，但在 {siteNameShort}Script 中，对象本身的用途远不止作为对象集中的单个部分。它们还用于表示运算器的输入。

### 声明对象

为了提高可读性并便于日后修改脚本，知行软件建议在 {siteNameShort}Script 中创建显式输入对象，并在单独的行中将其传递给运算器。对象通过 [arc:set](./keyword-reference/op-arc-set) 关键字创建、命名并赋予属性值：

```xml theme={null}
<arc:set item="input" attr="mask" value="*.txt" />
```

上面的代码片段将名为 `input` 的对象上的 `mask` 属性设置为值 `*.txt`。在这种情况下，输入对象就像 {siteNameShort}Script 中的变量。

不过，名为 `input` 的对象从未显式声明。相反，当您第一次尝试为其设置属性时，该对象就会被创建。在此示例中，如果输入对象不存在，则会创建该对象并设置 mask 属性。

<Tip>
  您也可以使用“简写”方法声明对象和属性。例如：

  ```xml theme={null}
  <arc:set attr="colors.myfavorite" value="green" />
  ```

  此代码片段创建一个 `colors` 对象，其 `myfavorite` 属性的值为 `green`。
</Tip>

### 通过查询字符串参数传递对象

作为创建显式输入对象的替代方法，您可以通过 [arc:call](./keyword-reference/op-arc-call) 查询字符串参数的形式将输入参数传递给运算器。为了说明显式声明对象与将对象作为参数传递之间的区别，请参考以下几行：它们声明一个名为 `file` 的对象，并将该对象传递给运算器以读取一行内容：

```xml theme={null}
<arc:set attr="file.file" value="[filepath]" />

<arc:call op="fileReadLine" in="file">
```

要使用查询字符串参数完成同样的操作，可以改用以下语法：

```xml theme={null}
<arc:call op="fileReadLine?file=[filePath | urlencode]">
```

<Note>使用此格式要求通过 `urlencode` 参数对参数进行 URL 编码。这可确保应用程序正确解析文件名中的特殊字符或保留字符，而不会出错。</Note>

### 选择属性值

要引用属性，请使用 `item.attribute` 语法（例如 `input.mask`）。要查询属性值，请将属性名放在方括号（\[ ]）中。这会告诉解释器您要计算该字符串，而不是将其解释为字符串文字。

例如，请参考以下代码片段：

```xml theme={null}
<arc:set item="item1" attr="attr1" value="value1"/>
<arc:set item="item1" attr="attr2" value="item1.attr1"/>
<arc:set item="item1" attr="attr3" value="[item1.attr1]"/>
```

结果如下：

* `item1.attr1` 被赋予文字字符串值 `value1`。
* `item1.attr2` 被赋予文字字符串值 `item1.attr1`。
* `item1.attr3` 被赋予值 `value1`，因为字符串 `[item1.attr1]` 会在运行时被计算为 `item1` 的 `attr1` 属性。

<Note>可以使用反斜杠转义字符串文字中的方括号。</Note>

### 默认对象

在 {siteNameShort}Script 的内部对象堆栈中，始终存在一个隐式、未命名的对象，即*默认对象*。虽然可以使用此对象编写完整脚本，但最佳实践是根据需要定义自己的显式输入和输出对象。这会让脚本更易读，并降低覆盖现有属性的风险。对于简单的脚本场景，可以在以下两种情况下使用默认对象，使脚本稍短且更易编写：

* 调用运算器：如果未指定其它对象，默认对象就是传递给脚本所调用运算器的对象。这意味着您可以使用 [arc:set](./keyword-reference/op-arc-set) 将属性写入默认的未命名对象，这些属性会作为输入传递给脚本中调用的下一个运算器。这是提供运算器必需参数的一种方式。
* 处理运算器或脚本输出中的当前对象：如果没有为运算器结果指定变量名，则在调用该运算器的 [arc:call](./keyword-reference/op-arc-call) 块中，默认对象会引用该运算器生成的当前对象。

通过省略 {siteNameShort}Script 关键字的 item 属性即可操作默认对象，如以下代码片段所示：

```xml theme={null}
<arc:set attr="path" value="." />
```

## 内置对象

除了脚本中声明的对象外，脚本作用域内还提供多个内置对象。内置对象为访问 HTTP 请求、响应等组成部分提供接口。这些对象有助于将 HTTP 请求中的输入映射到运算器输入。

以下各节介绍这些内置对象。

### 脚本输入（\_input）

脚本输入可以从 `_input` 对象读取。`_input` 对象包含脚本执行时 URL 查询字符串中的变量和 POST 数据。如果 POST 数据中存在同名变量，则会覆盖查询字符串中的值。

当您从脚本中的默认对象读取值时，实际上读取的是 `_input` 中的值；同样，写入默认对象的属性会与脚本输入一起作为参数传递给运算器。只有 info 块或脚本中定义的变量才可在 `_input` 对象中使用。

<Note>`_input` 在 [arc:call](./keyword-reference/op-arc-call) 块内不是默认对象。如果需要访问它，必须按名称引用。</Note>

### 脚本输出（\_out\[n]）

您可以通过默认对象或内置 `_outn` 对象访问 [arc:call](./keyword-reference/op-arc-call) 关键字生成的对象集中的当前对象，其中 `n` 是 [arc:call](./keyword-reference/op-arc-call) 关键字的嵌套级别。例如，如果位于单个 [arc:call](./keyword-reference/op-arc-call) 关键字内部，该对象名为 `_out1`。如果位于三层嵌套的 [arc:call](./keyword-reference/op-arc-call) 关键字内部，则对象名为 `_out3`。

### HTTP 请求（\_request）

您可以访问通过 URL 查询字符串传入的变量、POST 到脚本的变量，以及 `_request` 对象中作为属性集合的其它变量。要访问特定的属性集合，请使用集合名称作为要读取属性的前缀。例如，`[_request.qstring:name]` 读取查询字符串中变量 “name” 的值，而 `[_request.form:name]` 读取表单数据中变量 “name” 的值。

| 属性                | 描述                                                              |
| ----------------- | --------------------------------------------------------------- |
| `q[uery]string:*` | 访问查询字符串参数的值。                                                    |
| `form:*`          | 访问表单数据中的变量值。                                                    |
| `server:*`        | 访问服务器变量的值。                                                      |
| `body`            | 访问请求的原始内容（主体）。                                                  |
| `bodybase64`      | 访问请求的 base64 编码内容（主体）。                                          |
| `auth:*`          | 访问用户的身份验证信息。使用 `[_request.auth:isauthenticated]` 判断用户是否已通过身份验证。 |
| `other:*`         | 访问请求的其它信息。使用 `[_request.other:applicationpath]` 检索应用程序路径。       |

### HTTP 响应（\_response）

`_response` 对象允许脚本作者直接写入 HTTP 响应。您可以设置以下属性：

| 属性                  | 描述                                                          |
| ------------------- | ----------------------------------------------------------- |
| `cookie:*`          | 在响应中设置 cookie。属性名是带有 `cookie:` 前缀的 cookie 名称，属性值是 cookie 值。 |
| `writefile`         | 将指定路径的内容写入响应。                                               |
| `redirect`          | 将重定向头发送到客户端浏览器。这可用于将浏览器重定向到另一个 URL。                         |
| `statuscode`        | 设置响应的 HTTP 状态码。                                             |
| `statusdescription` | 设置响应的 HTTP 状态描述。                                            |

### HTTP 头（\_httpheaders）

`_httpheaders` 对象可在脚本和模板中轻松访问 HTTP 头。您可以读取此对象来读取 HTTP 请求头；也可以写入此对象来写入传出响应头。例如，可以使用如下行设置内容类型：

```xml theme={null}
<arc:set item="_httpheaders" attr="content-type" value="application/xml"/>
```

### HTTP Cookie（\_cookies）

使用 `_cookies` 对象可以检索请求中的 cookie，并在响应中设置 cookie。包含多个 key/value 对的 cookie 会表示为与 cookie 的 key/value 对相对应的属性集合。cookie 名称会作为集合中每个属性的前缀。

### ASP.NET 会话（\_session）

ASP.NET 会话变量可通过 {siteNameShort}Script 中的 `_session` 对象使用。存储在会话中的任何对象都可以作为此对象的属性访问。属性名表示用于在会话中存储该对象的键。

### {siteName} 消息（\_message）

当文件通过 {siteNameShort} [流程](../flows/flows)时，应用程序会向文件添加元数据。由原始文件和应用程序元数据组成的结果称为*消息*。

`_message` 对象在脚本上下文中提供对消息正文和元数据的访问（也可在能够解释脚本的端口字段中使用，例如 [Email Send 端口](../connectors/email-send)中的**主题**字段）。

<Note>{siteNameShort}Script 中的数组限制为 32768 个成员。如果消息包含重复超过 32768 次的头，则最旧的头会从消息中移除。</Note>

#### 元数据

消息元数据包括：

* 一个唯一 ID（称为 *MessageId*），无论文件名如何更改，它都可以识别文件
* 处理过程中失败和成功的信息
* 在流程中以编程方式提升的任何自定义元数据

要访问消息元数据，请使用 `_message` 对象的 `header:*` 属性。例如，当在 {siteNameShort} 中处理文件时发生错误，会向代表该文件的消息添加 `x-trapped-errordescription` 头。此头存储有关所发生错误的信息，包括发生错误的 ConnectorId 以及错误的调试信息。以下语法在脚本上下文中引用此头：

`[_message.header:x-trapped-errordescription]`

#### 正文

要访问消息正文，请使用 `_message` 对象的 `body` 属性，如下所示：

`[_message.body]`

这会以字符串形式返回消息正文。

#### 添加跟踪头

要向消息添加[跟踪头](../getting-started/administration/activity#tracked-headers)，请使用 `_message` 对象的 `trackedheader` 属性，如下所示：

```xml theme={null}
<arc:set attr="output.filepath" value="[filepath]" />
<arc:set attr="_message.trackedheader:myHeaderName" value="Myvalue" />
<arc:push item="output" />
```

#### 添加自定义头

要向文件添加自定义头，请设置端口推出的文件对象的 `Header:header_name` 属性。为清楚起见，先从一个脚本开始，该脚本将输入文件的未修改版本作为输出推出：

```xml theme={null}
<arc:set attr="outfile.FilePath" value="[FilePath]" />
<arc:push item="outfile" />
```

`[FilePath]` 变量会解析为输入文件的完整路径（和文件名），因此该脚本会使输出文件与输入文件相同。

此脚本中的以下新增内容会在推出文件之前向文件添加自定义头：

```xml theme={null}
<arc:set attr="outfile.FilePath" value="[FilePath]" />
<arc:set attr="outfile.Header:myHeaderName" value="myValue" />
<arc:push item="outfile" />
```

要让自定义头可在日志中搜索，请导航到**设置 > 高级**页面的**高级设置**部分中的**跟踪头**字段，并添加头名称。

#### 记录端口事件

要在 {siteNameShort}Script 中向 `_message` 正文添加端口定义事件的日志记录，请向消息添加 `log` 属性前缀、有效的日志级别条目以及 `value`。以下示例向日志文件添加一个 `Info` 行，其中包含属性 `value` 部分的文本：

```xml theme={null}
<arc:set attr="_message.log:info" value="This is an info level log entry" />
```

有效的日志级别条目如下：

* Error
* Warning
* Info
* Debug
* Trace

### 映射上下文（\_map）

`_map` 对象可在 [XML Map 端口](../connectors/xml-map/xml-map)中使用。在 `_map` 对象中设置的属性始终可供后续映射使用（换言之，这些属性不会被清除，且 `_map` 对象永远不会超出作用域）。

`_map` 对象适合存储在映射中某一点计算出来并在稍后引用的信息。例如，涉及 EDI 文档的映射可能需要计算文档中*行项目*的数量，然后在文档末尾的 CTT 段中包含此计数值。可以将*行项目*计数计算并存储为 `_map` 对象的属性，随后在 CTT 段映射中引用该属性。

### 应用程序日志（\_log）

`_log` 对象是进入 {siteNameShort} 应用程序日志的挂钩。将此对象的 `info` 属性设置为字符串，会使该字符串显示在应用程序日志中。例如：

```xml theme={null}
<arc:set attr="_log.info" value="this string appears in the Application Log when the script executes" />
```

您可以在同一脚本中多次设置此属性，以将多条消息记录到应用程序日志。无需清除或追加属性值；按上例设置属性值即可记录指定值。

### {siteName} 端口（\_connector）

`_connector` 对象提供对当前端口字段和属性的访问。可用属性与端口文件夹中 *port.cfg* 文件里存储的值相同，应使用以下语法访问：

`[_connector.propertyName]`

<Note>使用此对象需要端口中的脚本上下文。端口的**事件**选项卡始终提供此上下文，部分端口还可以在特殊的可配置字段中计算 {siteNameShort}Script。</Note>
