Skip to content

Commit

Permalink
Added XML support for load_data (#1769)
Browse files Browse the repository at this point in the history
Co-authored-by: doomy <2640792-_doomy@users.noreply.gitlab.com>
  • Loading branch information
piedoom and doomy authored Mar 4, 2022
1 parent a67370b commit 88e0624
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 5 deletions.
31 changes: 31 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/libs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ csv = "1"
base64 = "0.13"
serde_json = "1"
serde_yaml = "0.8"
quickxml_to_serde = "0.5"
url = "2"
syntect = "4"
once_cell = "1"
Expand Down
1 change: 1 addition & 0 deletions components/libs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub use num_format;
pub use once_cell;
pub use percent_encoding;
pub use pulldown_cmark;
pub use quickxml_to_serde;
pub use rayon;
pub use regex;
pub use relative_path;
Expand Down
61 changes: 61 additions & 0 deletions components/templates/src/global_fns/load_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum OutputFormat {
Csv,
Bibtex,
Plain,
Xml,
}

impl FromStr for OutputFormat {
Expand All @@ -57,6 +58,7 @@ impl FromStr for OutputFormat {
"csv" => Ok(OutputFormat::Csv),
"json" => Ok(OutputFormat::Json),
"bibtex" => Ok(OutputFormat::Bibtex),
"xml" => Ok(OutputFormat::Xml),
"plain" => Ok(OutputFormat::Plain),
format => Err(format!("Unknown output format {}", format).into()),
}
Expand All @@ -70,6 +72,7 @@ impl OutputFormat {
OutputFormat::Csv => "text/csv",
OutputFormat::Toml => "application/toml",
OutputFormat::Bibtex => "application/x-bibtex",
OutputFormat::Xml => "text/xml",
OutputFormat::Plain => "text/plain",
})
}
Expand Down Expand Up @@ -368,6 +371,7 @@ impl TeraFn for LoadData {
OutputFormat::Csv => load_csv(data),
OutputFormat::Json => load_json(data),
OutputFormat::Bibtex => load_bibtex(data),
OutputFormat::Xml => load_xml(data),
OutputFormat::Plain => to_value(data).map_err(|e| e.into()),
};

Expand Down Expand Up @@ -502,6 +506,42 @@ fn load_csv(csv_data: String) -> Result<Value> {
to_value(csv_value).map_err(|err| err.into())
}

/// Parse an XML string and convert it to a Tera Value
///
/// An example XML file `example.xml` could be:
/// ```xml
/// <root>
/// <headers>Number</headers>
/// <headers>Title</headers>
/// <records>
/// <item>1</item>
/// <item>Gutenberg</item>
/// </records>
/// <records>
/// <item>2</item>
/// <item>Printing</item>
/// </records>
/// </root>
/// ```
/// The json value output would be:
/// ```json
/// {
/// "root": {
/// "headers": ["Number", "Title"],
/// "records": [
/// ["1", "Gutenberg"],
/// ["2", "Printing"]
/// ]
/// }
/// }
/// ```
fn load_xml(xml_data: String) -> Result<Value> {
let xml_content: Value =
libs::quickxml_to_serde::xml_string_to_json(xml_data, &Default::default())
.map_err(|e| format!("{:?}", e))?;
Ok(xml_content)
}

#[cfg(test)]
mod tests {
use super::{DataSource, LoadData, OutputFormat};
Expand Down Expand Up @@ -1007,6 +1047,27 @@ mod tests {
)
}

#[test]
fn can_load_xml() {
let static_fn = LoadData::new(PathBuf::from("../utils/test-files"), None, PathBuf::new());
let mut args = HashMap::new();
args.insert("path".to_string(), to_value("test.xml").unwrap());
let result = static_fn.call(&args.clone()).unwrap();

assert_eq!(
result,
json!({
"root": {
"key": "value",
"array": [1, 2, 3],
"subpackage": {
"subkey": 5
}
}
})
)
}

#[test]
fn is_load_remote_data_using_post_method_with_different_body_not_cached() {
let _mjson = mock("POST", "/kr1zdgbm4y3")
Expand Down
9 changes: 9 additions & 0 deletions components/utils/test-files/test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<root>
<key>value</key>
<array>1</array>
<array>2</array>
<array>3</array>
<subpackage>
<subkey>5</subkey>
</subpackage>
</root>
9 changes: 4 additions & 5 deletions docs/content/documentation/templates/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ The method returns a map containing `width`, `height` and `format` (the lowercas
```

### `load_data`
Loads data from a file or URL. Supported file types include *toml*, *json*, *csv* and *bibtex* and only supports UTF-8 encoding.
Loads data from a file or URL. Supported file types include *toml*, *json*, *csv*, *bibtex* and *xml* and only supports UTF-8 encoding.
Any other file type will be loaded as plain text.

The `path` argument specifies the path to a local data file, according to the [File Searching Logic](@/documentation/templates/overview.md#file-searching-logic).
Expand All @@ -283,17 +283,16 @@ The snippet below outputs the HTML from a Wikipedia page, or "No data found" if
```

The optional `format` argument allows you to specify and override which data type is contained
within the specified file or URL. Valid entries are `toml`, `json`, `csv`, `bibtex`
or `plain`. If the `format` argument isn't specified, then the path extension is used.
within the specified file or URL. Valid entries are `toml`, `json`, `csv`, `bibtex`, `xml` or `plain`. If the `format` argument isn't specified, then the path extension is used.


```jinja2
{% set data = load_data(path="content/blog/story/data.txt", format="json") %}
```

Use the `plain` format for when your file has a toml/json/csv extension but you want to load it as plain text.
Use the `plain` format for when your file has a supported extension but you want to load it as plain text.

For *toml* and *json*, the data is loaded into a structure matching the original data file;
For *toml*, *json* and *xml*, the data is loaded into a structure matching the original data file;
however, for *csv* there is no native notion of such a structure. Instead, the data is separated
into a data structure containing *headers* and *records*. See the example below to see
how this works.
Expand Down

0 comments on commit 88e0624

Please sign in to comment.