mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
wip
This commit is contained in:
parent
c48b1612df
commit
4d9583d1ee
@ -1,15 +1,8 @@
|
|||||||
strings:
|
# above_cat
|
||||||
- a: banana
|
cat: # inline_cat
|
||||||
- a: cat
|
# above_array
|
||||||
- a: apple
|
array: # inline_array
|
||||||
|
- 3 # inline_3
|
||||||
numbers:
|
# above_4
|
||||||
- a: 12
|
- 4 # inline_4
|
||||||
- a: 13
|
# below_cat
|
||||||
- a: 120
|
|
||||||
|
|
||||||
|
|
||||||
obj:
|
|
||||||
- a: {cat: "adog"}
|
|
||||||
- a: {cat: "doga"}
|
|
||||||
- a: apple
|
|
@ -108,7 +108,8 @@ yq e -o=xml '.' sample.yml
|
|||||||
```
|
```
|
||||||
will output
|
will output
|
||||||
```xml
|
```xml
|
||||||
<cat>purrs</cat>```
|
<cat>purrs</cat>
|
||||||
|
```
|
||||||
|
|
||||||
## Encode xml: array
|
## Encode xml: array
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
@ -127,7 +128,8 @@ will output
|
|||||||
<pets>
|
<pets>
|
||||||
<cat>purrs</cat>
|
<cat>purrs</cat>
|
||||||
<cat>meows</cat>
|
<cat>meows</cat>
|
||||||
</pets>```
|
</pets>
|
||||||
|
```
|
||||||
|
|
||||||
## Encode xml: attributes
|
## Encode xml: attributes
|
||||||
Fields with the matching xml-attribute-prefix are assumed to be attributes.
|
Fields with the matching xml-attribute-prefix are assumed to be attributes.
|
||||||
@ -147,7 +149,8 @@ will output
|
|||||||
```xml
|
```xml
|
||||||
<cat name="tiger">
|
<cat name="tiger">
|
||||||
<meows>true</meows>
|
<meows>true</meows>
|
||||||
</cat>```
|
</cat>
|
||||||
|
```
|
||||||
|
|
||||||
## Encode xml: attributes with content
|
## Encode xml: attributes with content
|
||||||
Fields with the matching xml-content-name is assumed to be content.
|
Fields with the matching xml-content-name is assumed to be content.
|
||||||
@ -165,5 +168,33 @@ yq e -o=xml '.' sample.yml
|
|||||||
```
|
```
|
||||||
will output
|
will output
|
||||||
```xml
|
```xml
|
||||||
<cat name="tiger">cool</cat>```
|
<cat name="tiger">cool</cat>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Encode xml: comments
|
||||||
|
A best attempt is made to copy comments to xml.
|
||||||
|
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
# above_cat
|
||||||
|
cat: # inline_cat
|
||||||
|
# above_array
|
||||||
|
array: # inline_array
|
||||||
|
- val1 # inline_val1
|
||||||
|
# above_val2
|
||||||
|
- val2 # inline_val2
|
||||||
|
# below_cat
|
||||||
|
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq e -o=xml '.' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```xml
|
||||||
|
<!-- above_cat inline_cat--><cat><!-- above_array inline_array-->
|
||||||
|
<array><!-- inline_val1-->val1</array>
|
||||||
|
<array><!-- above_val2 inline_val2-->val2</array>
|
||||||
|
</cat><!-- below_cat-->
|
||||||
|
```
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package yqlib
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/magiconair/properties"
|
"github.com/magiconair/properties"
|
||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
@ -30,9 +29,7 @@ func (pe *propertiesEncoder) Encode(node *yaml.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yaml.Node, path string) error {
|
func (pe *propertiesEncoder) doEncode(p *properties.Properties, node *yaml.Node, path string) error {
|
||||||
p.SetComment(path,
|
p.SetComment(path, headAndLineComment(node))
|
||||||
strings.Replace(node.HeadComment, "#", "", 1)+
|
|
||||||
strings.Replace(node.LineComment, "#", "", 1))
|
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
case yaml.ScalarNode:
|
case yaml.ScalarNode:
|
||||||
_, _, err := p.Set(path, node.Value)
|
_, _, err := p.Set(path, node.Value)
|
||||||
|
@ -32,14 +32,20 @@ func (e *xmlEncoder) Encode(node *yaml.Node) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var charData xml.CharData = []byte("\n")
|
case yaml.DocumentNode:
|
||||||
err = e.xmlEncoder.EncodeToken(charData)
|
err := e.encodeComment(headAndLineComment(node))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = e.Encode(unwrapDoc(node))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = e.encodeComment(footComment(node))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return e.xmlEncoder.Flush()
|
|
||||||
case yaml.DocumentNode:
|
|
||||||
return e.Encode(unwrapDoc(node))
|
|
||||||
case yaml.ScalarNode:
|
case yaml.ScalarNode:
|
||||||
var charData xml.CharData = []byte(node.Value)
|
var charData xml.CharData = []byte(node.Value)
|
||||||
err := e.xmlEncoder.EncodeToken(charData)
|
err := e.xmlEncoder.EncodeToken(charData)
|
||||||
@ -47,9 +53,13 @@ func (e *xmlEncoder) Encode(node *yaml.Node) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return e.xmlEncoder.Flush()
|
return e.xmlEncoder.Flush()
|
||||||
}
|
default:
|
||||||
return fmt.Errorf("unsupported type %v", node.Tag)
|
return fmt.Errorf("unsupported type %v", node.Tag)
|
||||||
}
|
}
|
||||||
|
var charData xml.CharData = []byte("\n")
|
||||||
|
return e.xmlEncoder.EncodeToken(charData)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (e *xmlEncoder) encodeTopLevelMap(node *yaml.Node) error {
|
func (e *xmlEncoder) encodeTopLevelMap(node *yaml.Node) error {
|
||||||
for i := 0; i < len(node.Content); i += 2 {
|
for i := 0; i < len(node.Content); i += 2 {
|
||||||
@ -57,7 +67,16 @@ func (e *xmlEncoder) encodeTopLevelMap(node *yaml.Node) error {
|
|||||||
value := node.Content[i+1]
|
value := node.Content[i+1]
|
||||||
|
|
||||||
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.encodeComment(headAndLineComment(key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = e.doEncode(value, start)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = e.encodeComment(footComment(key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -65,6 +84,22 @@ func (e *xmlEncoder) encodeTopLevelMap(node *yaml.Node) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *xmlEncoder) encodeStart(node *yaml.Node, start xml.StartElement) error {
|
||||||
|
err := e.xmlEncoder.EncodeToken(start)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return e.encodeComment(headAndLineComment(node))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *xmlEncoder) encodeEnd(node *yaml.Node, start xml.StartElement) error {
|
||||||
|
err := e.xmlEncoder.EncodeToken(start.End())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return e.encodeComment(footComment(node))
|
||||||
|
}
|
||||||
|
|
||||||
func (e *xmlEncoder) doEncode(node *yaml.Node, start xml.StartElement) error {
|
func (e *xmlEncoder) doEncode(node *yaml.Node, start xml.StartElement) error {
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
case yaml.MappingNode:
|
case yaml.MappingNode:
|
||||||
@ -72,22 +107,33 @@ func (e *xmlEncoder) doEncode(node *yaml.Node, start xml.StartElement) error {
|
|||||||
case yaml.SequenceNode:
|
case yaml.SequenceNode:
|
||||||
return e.encodeArray(node, start)
|
return e.encodeArray(node, start)
|
||||||
case yaml.ScalarNode:
|
case yaml.ScalarNode:
|
||||||
err := e.xmlEncoder.EncodeToken(start)
|
err := e.encodeStart(node, start)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var charData xml.CharData = []byte(node.Value)
|
var charData xml.CharData = []byte(node.Value)
|
||||||
err = e.xmlEncoder.EncodeToken(charData)
|
err = e.xmlEncoder.EncodeToken(charData)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return e.xmlEncoder.EncodeToken(start.End())
|
|
||||||
|
return e.encodeEnd(node, start)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unsupported type %v", node.Tag)
|
return fmt.Errorf("unsupported type %v", node.Tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *xmlEncoder) encodeComment(commentStr string) error {
|
||||||
|
if commentStr != "" {
|
||||||
|
var comment xml.Comment = []byte(commentStr)
|
||||||
|
err := e.xmlEncoder.EncodeToken(comment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *xmlEncoder) encodeArray(node *yaml.Node, start xml.StartElement) error {
|
func (e *xmlEncoder) encodeArray(node *yaml.Node, start xml.StartElement) error {
|
||||||
for i := 0; i < len(node.Content); i++ {
|
for i := 0; i < len(node.Content); i++ {
|
||||||
value := node.Content[i]
|
value := node.Content[i]
|
||||||
@ -116,7 +162,7 @@ func (e *xmlEncoder) encodeMap(node *yaml.Node, start xml.StartElement) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := e.xmlEncoder.EncodeToken(start)
|
err := e.encodeStart(node, start)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -126,6 +172,11 @@ 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]
|
||||||
|
|
||||||
|
err := e.encodeComment(headAndLineComment(key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(key.Value, e.attributePrefix) && key.Value != e.contentName {
|
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)
|
||||||
@ -140,7 +191,11 @@ func (e *xmlEncoder) encodeMap(node *yaml.Node, start xml.StartElement) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err = e.encodeComment(footComment(key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.xmlEncoder.EncodeToken(start.End())
|
return e.encodeEnd(node, start)
|
||||||
}
|
}
|
||||||
|
@ -236,6 +236,15 @@ func createScalarNode(value interface{}, stringValue string) *yaml.Node {
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func headAndLineComment(node *yaml.Node) string {
|
||||||
|
return strings.Replace(node.HeadComment, "#", "", 1) +
|
||||||
|
strings.Replace(node.LineComment, "#", "", 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func footComment(node *yaml.Node) string {
|
||||||
|
return strings.Replace(node.FootComment, "#", "", 1)
|
||||||
|
}
|
||||||
|
|
||||||
func createValueOperation(value interface{}, stringValue string) *Operation {
|
func createValueOperation(value interface{}, stringValue string) *Operation {
|
||||||
var node *yaml.Node = createScalarNode(value, stringValue)
|
var node *yaml.Node = createScalarNode(value, stringValue)
|
||||||
|
|
||||||
|
@ -52,6 +52,22 @@ type xmlScenario struct {
|
|||||||
encodeScenario bool
|
encodeScenario bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var yamlWithComments = `# above_cat
|
||||||
|
cat: # inline_cat
|
||||||
|
# above_array
|
||||||
|
array: # inline_array
|
||||||
|
- val1 # inline_val1
|
||||||
|
# above_val2
|
||||||
|
- val2 # inline_val2
|
||||||
|
# below_cat
|
||||||
|
`
|
||||||
|
|
||||||
|
var expectedXmlWithComments = `<!-- above_cat inline_cat--><cat><!-- above_array inline_array-->
|
||||||
|
<array><!-- inline_val1-->val1</array>
|
||||||
|
<array><!-- above_val2 inline_val2-->val2</array>
|
||||||
|
</cat><!-- below_cat-->
|
||||||
|
`
|
||||||
|
|
||||||
var xmlScenarios = []xmlScenario{
|
var xmlScenarios = []xmlScenario{
|
||||||
{
|
{
|
||||||
description: "Parse xml: simple",
|
description: "Parse xml: simple",
|
||||||
@ -79,33 +95,40 @@ var xmlScenarios = []xmlScenario{
|
|||||||
{
|
{
|
||||||
description: "Encode xml: simple",
|
description: "Encode xml: simple",
|
||||||
input: "cat: purrs",
|
input: "cat: purrs",
|
||||||
expected: "<cat>purrs</cat>",
|
expected: "<cat>purrs</cat>\n",
|
||||||
encodeScenario: true,
|
encodeScenario: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Encode xml: array",
|
description: "Encode xml: array",
|
||||||
input: "pets:\n cat:\n - purrs\n - meows",
|
input: "pets:\n cat:\n - purrs\n - meows",
|
||||||
expected: "<pets>\n <cat>purrs</cat>\n <cat>meows</cat>\n</pets>",
|
expected: "<pets>\n <cat>purrs</cat>\n <cat>meows</cat>\n</pets>\n",
|
||||||
encodeScenario: true,
|
encodeScenario: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Encode xml: attributes",
|
description: "Encode xml: attributes",
|
||||||
subdescription: "Fields with the matching xml-attribute-prefix are assumed to be attributes.",
|
subdescription: "Fields with the matching xml-attribute-prefix are assumed to be attributes.",
|
||||||
input: "cat:\n +name: tiger\n meows: true\n",
|
input: "cat:\n +name: tiger\n meows: true\n",
|
||||||
expected: "<cat name=\"tiger\">\n <meows>true</meows>\n</cat>",
|
expected: "<cat name=\"tiger\">\n <meows>true</meows>\n</cat>\n",
|
||||||
encodeScenario: true,
|
encodeScenario: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
skipDoc: true,
|
skipDoc: true,
|
||||||
input: "cat:\n ++name: tiger\n meows: true\n",
|
input: "cat:\n ++name: tiger\n meows: true\n",
|
||||||
expected: "<cat +name=\"tiger\">\n <meows>true</meows>\n</cat>",
|
expected: "<cat +name=\"tiger\">\n <meows>true</meows>\n</cat>\n",
|
||||||
encodeScenario: true,
|
encodeScenario: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Encode xml: attributes with content",
|
description: "Encode xml: attributes with content",
|
||||||
subdescription: "Fields with the matching xml-content-name is assumed to be content.",
|
subdescription: "Fields with the matching xml-content-name is assumed to be content.",
|
||||||
input: "cat:\n +name: tiger\n +content: cool\n",
|
input: "cat:\n +name: tiger\n +content: cool\n",
|
||||||
expected: "<cat name=\"tiger\">cool</cat>",
|
expected: "<cat name=\"tiger\">cool</cat>\n",
|
||||||
|
encodeScenario: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Encode xml: comments",
|
||||||
|
subdescription: "A best attempt is made to copy comments to xml.",
|
||||||
|
input: yamlWithComments,
|
||||||
|
expected: expectedXmlWithComments,
|
||||||
encodeScenario: true,
|
encodeScenario: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user