mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-13 22:38:04 +00:00
wip
This commit is contained in:
parent
ae8df5ea87
commit
6bcbd873a6
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<cat>3f</cat>
|
<cat>3f</cat>
|
||||||
<dog>meow:as</dog>
|
<dog>meow:as</dog>
|
||||||
<dog3>true</dog3>
|
<dog3>true</dog3>
|
@ -14,6 +14,7 @@ These operators are useful to process yaml documents that have stringified embed
|
|||||||
| Properties | | to_props/@props |
|
| Properties | | to_props/@props |
|
||||||
| CSV | | to_csv/@csv |
|
| CSV | | to_csv/@csv |
|
||||||
| TSV | | to_tsv/@tsv |
|
| TSV | | to_tsv/@tsv |
|
||||||
|
| XML | from_xml | |
|
||||||
|
|
||||||
|
|
||||||
CSV and TSV format both accept either a single array or scalars (representing a single row), or an array of array of scalars (representing multiple rows).
|
CSV and TSV format both accept either a single array or scalars (representing a single row), or an array of array of scalars (representing multiple rows).
|
||||||
|
@ -141,3 +141,22 @@ will output
|
|||||||
</cat>
|
</cat>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Encode xml: attributes with content
|
||||||
|
Fields with the matching xml-content-name is assumed to be content.
|
||||||
|
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
cat:
|
||||||
|
+name: tiger
|
||||||
|
+content: cool
|
||||||
|
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq e -o=xml '.' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```xml
|
||||||
|
<cat name="tiger">cool</cat>
|
||||||
|
```
|
||||||
|
|
||||||
|
@ -12,9 +12,10 @@ import (
|
|||||||
type xmlEncoder struct {
|
type xmlEncoder struct {
|
||||||
xmlEncoder *xml.Encoder
|
xmlEncoder *xml.Encoder
|
||||||
attributePrefix string
|
attributePrefix string
|
||||||
|
contentName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewXmlEncoder(writer io.Writer, indent int, attributePrefix string) Encoder {
|
func NewXmlEncoder(writer io.Writer, indent int, attributePrefix string, contentName string) Encoder {
|
||||||
encoder := xml.NewEncoder(writer)
|
encoder := xml.NewEncoder(writer)
|
||||||
var indentString = ""
|
var indentString = ""
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ func NewXmlEncoder(writer io.Writer, indent int, attributePrefix string) Encoder
|
|||||||
indentString = indentString + " "
|
indentString = indentString + " "
|
||||||
}
|
}
|
||||||
encoder.Indent("", indentString)
|
encoder.Indent("", indentString)
|
||||||
return &xmlEncoder{encoder, attributePrefix}
|
return &xmlEncoder{encoder, attributePrefix, contentName}
|
||||||
}
|
}
|
||||||
func (e *xmlEncoder) Encode(node *yaml.Node) error {
|
func (e *xmlEncoder) Encode(node *yaml.Node) error {
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
@ -92,7 +93,7 @@ func (e *xmlEncoder) encodeMap(node *yaml.Node, start xml.StartElement) error {
|
|||||||
key := node.Content[i]
|
key := node.Content[i]
|
||||||
value := node.Content[i+1]
|
value := node.Content[i+1]
|
||||||
|
|
||||||
if strings.HasPrefix(key.Value, e.attributePrefix) {
|
if strings.HasPrefix(key.Value, e.attributePrefix) && key.Value != e.contentName {
|
||||||
if value.Kind == yaml.ScalarNode {
|
if value.Kind == yaml.ScalarNode {
|
||||||
attributeName := strings.Replace(key.Value, e.attributePrefix, "", 1)
|
attributeName := strings.Replace(key.Value, e.attributePrefix, "", 1)
|
||||||
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: attributeName}, Value: value.Value})
|
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: attributeName}, Value: value.Value})
|
||||||
@ -112,12 +113,19 @@ func (e *xmlEncoder) encodeMap(node *yaml.Node, start xml.StartElement) error {
|
|||||||
key := node.Content[i]
|
key := node.Content[i]
|
||||||
value := node.Content[i+1]
|
value := node.Content[i+1]
|
||||||
|
|
||||||
if !strings.HasPrefix(key.Value, e.attributePrefix) {
|
if !strings.HasPrefix(key.Value, e.attributePrefix) && key.Value != e.contentName {
|
||||||
start := xml.StartElement{Name: xml.Name{Local: key.Value}}
|
start := xml.StartElement{Name: xml.Name{Local: key.Value}}
|
||||||
err := e.doEncode(value, start)
|
err := e.doEncode(value, start)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else if key.Value == e.contentName {
|
||||||
|
// directly encode the contents
|
||||||
|
var charData xml.CharData = []byte(value.Value)
|
||||||
|
err = e.xmlEncoder.EncodeToken(charData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ const (
|
|||||||
PropsOutputFormat
|
PropsOutputFormat
|
||||||
CsvOutputFormat
|
CsvOutputFormat
|
||||||
TsvOutputFormat
|
TsvOutputFormat
|
||||||
|
XmlOutputFormat
|
||||||
)
|
)
|
||||||
|
|
||||||
func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
||||||
@ -39,6 +40,8 @@ func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
|||||||
return CsvOutputFormat, nil
|
return CsvOutputFormat, nil
|
||||||
case "tsv", "t":
|
case "tsv", "t":
|
||||||
return TsvOutputFormat, nil
|
return TsvOutputFormat, nil
|
||||||
|
case "xml", "x":
|
||||||
|
return XmlOutputFormat, nil
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("unknown format '%v' please use [yaml|json|props|csv|tsv]", format)
|
return 0, fmt.Errorf("unknown format '%v' please use [yaml|json|props|csv|tsv]", format)
|
||||||
}
|
}
|
||||||
@ -104,6 +107,8 @@ func (p *resultsPrinter) printNode(node *yaml.Node, writer io.Writer) error {
|
|||||||
encoder = NewCsvEncoder(writer, '\t')
|
encoder = NewCsvEncoder(writer, '\t')
|
||||||
case YamlOutputFormat:
|
case YamlOutputFormat:
|
||||||
encoder = NewYamlEncoder(writer, p.indent, p.colorsEnabled)
|
encoder = NewYamlEncoder(writer, p.indent, p.colorsEnabled)
|
||||||
|
case XmlOutputFormat:
|
||||||
|
encoder = NewXmlEncoder(writer, p.indent, "+", "+content")
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoder.Encode(node)
|
return encoder.Encode(node)
|
||||||
|
@ -28,7 +28,7 @@ func yamlToXml(sampleYaml string, indent int) string {
|
|||||||
var output bytes.Buffer
|
var output bytes.Buffer
|
||||||
writer := bufio.NewWriter(&output)
|
writer := bufio.NewWriter(&output)
|
||||||
|
|
||||||
var encoder = NewXmlEncoder(writer, indent, "+")
|
var encoder = NewXmlEncoder(writer, indent, "+", "+content")
|
||||||
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml", 0, NewYamlDecoder())
|
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml", 0, NewYamlDecoder())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -101,6 +101,13 @@ var xmlScenarios = []xmlScenario{
|
|||||||
expected: "<cat +name=\"tiger\">\n <meows>true</meows>\n</cat>",
|
expected: "<cat +name=\"tiger\">\n <meows>true</meows>\n</cat>",
|
||||||
encodeScenario: true,
|
encodeScenario: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "Encode xml: attributes with content",
|
||||||
|
subdescription: "Fields with the matching xml-content-name is assumed to be content.",
|
||||||
|
input: "cat:\n +name: tiger\n +content: cool\n",
|
||||||
|
expected: "<cat name=\"tiger\">cool</cat>",
|
||||||
|
encodeScenario: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
//encode
|
//encode
|
||||||
@ -121,7 +128,7 @@ func documentXmlScenario(t *testing.T, w *bufio.Writer, i interface{}) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if s.encodeScenario {
|
if s.encodeScenario {
|
||||||
documentXmlEncodeScenario(t, w, s)
|
documentXmlEncodeScenario(w, s)
|
||||||
} else {
|
} else {
|
||||||
documentXmlDecodeScenario(t, w, s)
|
documentXmlDecodeScenario(t, w, s)
|
||||||
}
|
}
|
||||||
@ -157,7 +164,7 @@ func documentXmlDecodeScenario(t *testing.T, w *bufio.Writer, s xmlScenario) {
|
|||||||
writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", output.String()))
|
writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", output.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func documentXmlEncodeScenario(t *testing.T, w *bufio.Writer, s xmlScenario) {
|
func documentXmlEncodeScenario(w *bufio.Writer, s xmlScenario) {
|
||||||
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
|
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
|
||||||
|
|
||||||
if s.subdescription != "" {
|
if s.subdescription != "" {
|
||||||
|
Loading…
Reference in New Issue
Block a user