Skip to content

Commit

Permalink
Merge pull request #5 from prakanth97/issue_6092
Browse files Browse the repository at this point in the history
Fix found bugs in XML data library
  • Loading branch information
prakanth97 authored Mar 20, 2024
2 parents 9b8776c + 0d7066b commit 7ed4f4b
Show file tree
Hide file tree
Showing 26 changed files with 1,900 additions and 241 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ jobs:
uses: ballerina-platform/ballerina-standard-library/.github/workflows/release-package-template.yml@main
secrets: inherit
with:
package-name: persist
package-name: data.xmldata
package-org: ballerina
144 changes: 94 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public function main() returns error? {
io:println(book);
}
type Book record {|
type Book record {
int id;
string title;
string author;
|};
};
```

### Converting an external XML document to a Record value
Expand All @@ -52,11 +52,11 @@ public function main() returns error? {
io:println(book);
}
type Book record {|
type Book record {
int id;
string title;
string author;
|};
};
```

Make sure to handle possible errors that may arise during the file reading or XML to record conversion process. The `check` keyword is utilized to handle these errors, but more sophisticated error handling can be implemented as per your requirements.
Expand All @@ -69,7 +69,7 @@ Take for instance the following XML snippet:

```xml
<book>
<id>0</id>
<id>601970</id>
<title>string</title>
<author>string</author>
</book>
Expand All @@ -80,11 +80,11 @@ XML data is inherently hierarchical, forming a tree structure. In the given exam
A straightforward record representation of the above XML data is:

```ballerina
type Book record {|
type Book record {
int id;
string title;
string author;
|};
};
```

In this representation, the XML data is efficiently translated into a record value. The `book` element is mapped to a record of type `Book`, and the child elements `id`, `title`, and `author` are converted into record fields of types `int` and `string` correspondingly.
Expand All @@ -99,7 +99,7 @@ Consider the XML snippet:

```xml
<book>
<id>0</id>
<id>601970</id>
<title-name>string</title-name>
<author-name>string</author-name>
</book>
Expand All @@ -108,27 +108,27 @@ Consider the XML snippet:
The canonical representation of the above XML as a Ballerina record is:

```ballerina
type Book record {|
type Book record {
int id;
string 'title\-name';
string 'author\-name';
|};
string title\-name;
string author\-name;
};
```

Observe how the XML element names `title-name` and `author-name` are represented using delimited identifiers in Ballerina; the `-` characters in the XML element names are escaped using the `\` character.
Observe how the XML element names `title-name` and `author-name` are represented using delimited identifiers in Ballerina; the `-` characters in the XML element names are escaped using the `\ ` character.

Moreover, the `@Name` annotation can be utilized to explicitly specify the name of the record field, providing control over the translation process:

```ballerina
import ballerina/data.xmldata;
type Book record {|
type Book record {
int id;
@xmldata:Name { value: "title-name" }
string title;
@xmldata:Name { value: "author-name" }
string author;
|};
};
```

### XML Attributes
Expand All @@ -139,7 +139,7 @@ Consider the following XML snippet:

```xml
<book lang="en" price="10.5">
<id>0</id>
<id>601970</id>
<title>string</title>
<author>string</author>
</book>
Expand All @@ -148,16 +148,16 @@ Consider the following XML snippet:
The canonical representation of the above XML as a Ballerina record is:

```ballerina
type Book record {|
type Book record {
string lang;
decimal price;
int id;
string title;
string author;
|};
};
```

Additionally the `@Attribute` annotation can be utilized to explicitly specify the name of the record field, providing control over the translation process.
Additionally, the `@Attribute` annotation can be used to explicitly specify the field as an attribute providing control over the translation process. When element and attribute have same name in the same scope the priority is given to the element unless the expected record field has the `@Attribute` annotation.

### Child Elements

Expand All @@ -167,7 +167,7 @@ Examine the XML snippet below:

```xml
<book>
<id>0</id>
<id>601970</id>
<title>string</title>
<author>
<name>string</name>
Expand All @@ -179,16 +179,16 @@ Examine the XML snippet below:
The canonical representation of the above XML as a Ballerina record is:

```ballerina
type Book record {|
type Book record {
int id;
string title;
Author author;
|};
};
type Author record {|
type Author record {
string name;
string country;
|};
};
```

In this transformation, child elements, like the `author` element containing its own sub-elements, are converted into nested records. This maintains the hierarchical structure of the XML data within the Ballerina type system, enabling intuitive and type-safe data manipulation.
Expand All @@ -198,14 +198,14 @@ Alternatively, inline type definitions offer a compact method for representing c
Consider the subsequent Ballerina record definition, which employs inline type definition for the `author` field:

```ballerina
type Book record {|
type Book record {
int id;
string title;
record {|
record {
string name;
string country;
|} author;
|};
} author;
};
```

### XML Text Content
Expand All @@ -216,7 +216,7 @@ Consider the XML snippet below:

```xml
<book>
<id>0</id>
<id>601970</id>
<title>string</title>
<author>string</author>
<available>true</available>
Expand All @@ -227,13 +227,13 @@ Consider the XML snippet below:
The translation into a Ballerina record would be as follows:

```ballerina
type Book record {|
type Book record {
int id;
string title;
string author;
boolean available;
decimal price;
|};
};
```

In scenarios where the parent XML element of text content also includes attributes, the XML text content can be represented by a `string` type field named `#content` within a record type, with the attributes being mapped to their respective fields.
Expand All @@ -242,7 +242,7 @@ For instance, examine this XML:

```xml
<book>
<id>0</id>
<id>601970</id>
<title lang="en">string</title>
<price>10.5</price>
</book>
Expand All @@ -251,20 +251,18 @@ For instance, examine this XML:
The canonical translation of XML to a Ballerina record is as such:

```ballerina
type Book record {|
type Book record {
int id;
Title title;
decimal price;
|};
};
type Title record {|
type Title record {
string \#content;
string lang;
|};
};
```

Modifications to the default behavior for converting numerical values can be achieved by providing `Options` mappings to the respective functions. This enables developers to choose specific data types and exert finer control over the conversion process.

### XML Namespaces

XML namespaces are accommodated by the library, supporting the translation of XML data that contains namespace prefixes. However, the presence of XML namespaces is not mandatory, and the library is capable of processing XML data without namespaces. Should namespaces be present, they will be utilized to resolve the names of XML elements and attributes.
Expand All @@ -275,7 +273,7 @@ Examine the XML snippet below with default namespaces:

```xml
<book xmlns="http://example.com/book">
<id>0</id>
<id>601970</id>
<title>string</title>
<author>string</author>
</book>
Expand All @@ -284,11 +282,11 @@ Examine the XML snippet below with default namespaces:
The translation into a Ballerina record would be:

```ballerina
type Book record {|
type Book record {
int id;
string title;
string author;
|};
};
```

Incorporating namespace validation yields:
Expand All @@ -299,18 +297,18 @@ import ballerina/data.xmldata;
@xmldata:Namespace {
uri: "http://example.com/book"
}
type Book record {|
type Book record {
int id;
string title;
string author;
|};
};
```

Here is the same XML snippet with a namespace prefix:

```xml
<bk:book xmlns:bk="http://example.com/book">
<bk:id>0</bk:id>
<bk:id>601970</bk:id>
<bk:title>string</bk:title>
<bk:author>string</bk:author>
</bk:book>
Expand All @@ -321,13 +319,59 @@ The translation into a Ballerina record would be:
```ballerina
import ballerina/data.xmldata;
@xmldata:Namespace {
uri: "http://example.com/book"
}
type Book record {|
@xmldata:Namespace {
uri: "http://example.com/book"
}
int id;
@xmldata:Namespace {
uri: "http://example.com/book"
}
string title;
@xmldata:Namespace {
uri: "http://example.com/book"
}
string author;
|};
```

Here is the same XML snippet with a namespace prefix:

```xml
<bk:book xmlns:bk="http://example.com/book" xmlns:au="http://example.com/author">
<bk:id>601970</bk:id>
<bk:title>string</bk:title>
<au:author>string</au:author>
</bk:book>
```

The translation into a Ballerina record would be:

```ballerina
import ballerina/data.xmldata;
@xmldata:Namespace {
uri: "http://example.com/book",
prefix: "bk"
}
type Book record {|
@xmldata:Namespace {
uri: "http://example.com/book",
prefix: "bk"
}
int id;
@xmldata:Namespace {
uri: "http://example.com/book",
prefix: "bk"
}
string title;
@xmldata:Namespace {
uri: "http://example.com/author",
prefix: "au"
}
string author;
|};
```
Expand All @@ -342,7 +386,7 @@ Take the following XML snippet as an example:

```xml
<book>
<id>0</id>
<id>601970</id>
<title>string</title>
<author>string</author>
<author>string</author>
Expand All @@ -353,11 +397,11 @@ Take the following XML snippet as an example:
The canonical representation of this XML as a Ballerina record is:

```ballerina
type Book record {|
type Book record {
int id;
string title;
string[] author;
|};
};
```

### Controlling Which Elements to Convert
Expand All @@ -368,7 +412,7 @@ Take this XML snippet as an example:

```xml
<book lang="en">
<id>0</id>
<id>601970</id>
<title lang="en">string</title>
<author>string</author>
<price>10.5</price>
Expand All @@ -387,10 +431,10 @@ type Book record {|
However, if the rest field is utilized (or if the record type is defined as an open record), all elements in the XML data will be transformed into record fields:

```ballerina
type Book record {|
type Book record {
int id;
string title;
|};
};
```

In this instance, all other elements in the XML data, such as `author` and `price` along with their attributes, will be transformed into `string` type fields with the corresponding element name as the key.
Expand Down
2 changes: 1 addition & 1 deletion ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["Ballerina"]
keywords = ["xml"]
repository = "https://github.com/ballerina-platform/module-ballerina-data-xmldata"
license = ["Apache-2.0"]
distribution = "2201.8.1"
distribution = "2201.8.5"
export = ["data.xmldata"]

[[platform.java17.dependency]]
Expand Down
Loading

0 comments on commit 7ed4f4b

Please sign in to comment.