diff --git a/pkg/yqlib/decoder_xml.go b/pkg/yqlib/decoder_xml.go
index a3dffeb7..d74c579a 100644
--- a/pkg/yqlib/decoder_xml.go
+++ b/pkg/yqlib/decoder_xml.go
@@ -12,35 +12,16 @@ import (
)
type xmlDecoder struct {
- reader io.Reader
- readAnything bool
- attributePrefix string
- directiveName string
- procInstPrefix string
- contentName string
- strictMode bool
- keepNamespace bool
- useRawToken bool
- finished bool
- skipDirectives bool
- skipProcInst bool
+ reader io.Reader
+ readAnything bool
+ finished bool
+ prefs xmlPreferences
}
-func NewXMLDecoder(attributePrefix string, contentName string, strictMode bool, keepNamespace bool, useRawToken bool, skipDirectives bool, skipProcInst bool) Decoder {
- if contentName == "" {
- contentName = "content"
- }
+func NewXMLDecoder(prefs xmlPreferences) Decoder {
return &xmlDecoder{
- attributePrefix: attributePrefix,
- contentName: contentName,
- finished: false,
- strictMode: strictMode,
- keepNamespace: keepNamespace,
- useRawToken: useRawToken,
- directiveName: "_directive_",
- procInstPrefix: "_procInst_",
- skipDirectives: skipDirectives,
- skipProcInst: skipProcInst,
+ finished: false,
+ prefs: prefs,
}
}
@@ -75,7 +56,7 @@ func (dec *xmlDecoder) createMap(n *xmlNode) (*yaml.Node, error) {
yamlNode := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
if len(n.Data) > 0 {
- label := dec.contentName
+ label := dec.prefs.ContentName
labelNode := createScalarNode(label, label)
labelNode.HeadComment = dec.processComment(n.HeadComment)
labelNode.FootComment = dec.processComment(n.FootComment)
@@ -211,7 +192,7 @@ type element struct {
// of the map keys.
func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
xmlDec := xml.NewDecoder(dec.reader)
- xmlDec.Strict = dec.strictMode
+ xmlDec.Strict = dec.prefs.StrictMode
// That will convert the charset if the provided XML is non-UTF-8
xmlDec.CharsetReader = charset.NewReaderLabel
@@ -222,7 +203,7 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
}
getToken := func() (xml.Token, error) {
- if dec.useRawToken {
+ if dec.prefs.UseRawToken {
return xmlDec.RawToken()
}
return xmlDec.Token()
@@ -250,12 +231,12 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
// Extract attributes as children
for _, a := range se.Attr {
- if dec.keepNamespace {
+ if dec.prefs.KeepNamespace {
if a.Name.Space != "" {
a.Name.Local = a.Name.Space + ":" + a.Name.Local
}
}
- elem.n.AddChild(dec.attributePrefix+a.Name.Local, &xmlNode{Data: a.Value})
+ elem.n.AddChild(dec.prefs.AttributePrefix+a.Name.Local, &xmlNode{Data: a.Value})
}
case xml.CharData:
// Extract XML data (if any)
@@ -289,12 +270,12 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
}
case xml.ProcInst:
- if !dec.skipProcInst {
- elem.n.AddChild(dec.procInstPrefix+se.Target, &xmlNode{Data: string(se.Inst)})
+ if !dec.prefs.SkipProcInst {
+ elem.n.AddChild(dec.prefs.ProcInstPrefix+se.Target, &xmlNode{Data: string(se.Inst)})
}
case xml.Directive:
- if !dec.skipDirectives {
- elem.n.AddChild(dec.directiveName, &xmlNode{Data: string(se)})
+ if !dec.prefs.SkipDirectives {
+ elem.n.AddChild(dec.prefs.DirectiveName, &xmlNode{Data: string(se)})
}
}
}
diff --git a/pkg/yqlib/doc/usage/xml.md b/pkg/yqlib/doc/usage/xml.md
index 3d668506..f0d80bf4 100644
--- a/pkg/yqlib/doc/usage/xml.md
+++ b/pkg/yqlib/doc/usage/xml.md
@@ -30,7 +30,7 @@ yq -p=xml '.' sample.xml
```
will output
```yaml
-_procInst_xml: version="1.0" encoding="UTF-8"
++p_xml: version="1.0" encoding="UTF-8"
cat:
says: meow
legs: "4"
@@ -55,7 +55,7 @@ yq -p=xml ' (.. | select(tag == "!!str")) |= from_yaml' sample.xml
```
will output
```yaml
-_procInst_xml: version="1.0" encoding="UTF-8"
++p_xml: version="1.0" encoding="UTF-8"
cat:
says: meow
legs: 4
@@ -77,7 +77,7 @@ yq -p=xml '.' sample.xml
```
will output
```yaml
-_procInst_xml: version="1.0" encoding="UTF-8"
++p_xml: version="1.0" encoding="UTF-8"
animal:
- cat
- goat
@@ -99,9 +99,9 @@ yq -p=xml '.' sample.xml
```
will output
```yaml
-_procInst_xml: version="1.0" encoding="UTF-8"
++p_xml: version="1.0" encoding="UTF-8"
cat:
- +legs: "4"
+ +@legs: "4"
legs: "7"
```
@@ -119,14 +119,14 @@ yq -p=xml '.' sample.xml
```
will output
```yaml
-_procInst_xml: version="1.0" encoding="UTF-8"
++p_xml: version="1.0" encoding="UTF-8"
cat:
+content: meow
- +legs: "4"
+ +@legs: "4"
```
## Parse xml: custom dtd
-DTD entities are ignored.
+DTD entities are processed as directives.
Given a sample.xml file of:
```xml
@@ -142,18 +142,45 @@ Given a sample.xml file of:
```
then
```bash
-yq -p=xml '.' sample.xml
+yq -p=xml -o=xml '.' sample.xml
```
will output
-```yaml
-_procInst_xml: version="1.0"
-_directive_: |-
- DOCTYPE root [
-
-
- ]
-root:
- item: '&writer;©right;'
+```xml
+
+
+
+]>
+
+ - &writer;©right;
+
+```
+
+## Parse xml: skip custom dtd
+DTDs are directives, skip over directives to skip DTDs.
+
+Given a sample.xml file of:
+```xml
+
+
+
+
+]>
+
+ - &writer;©right;
+
+```
+then
+```bash
+yq -p=xml -o=xml --xml-skip-directives '.' sample.xml
+```
+will output
+```xml
+
+
+ - &writer;©right;
+
```
## Parse xml: with comments
@@ -225,7 +252,7 @@ will output
instead of
```xml
-
+
```
## Parse xml: keep raw attribute namespace
@@ -244,7 +271,7 @@ yq -p=xml -o=xml --xml-keep-namespace --xml-raw-token '.' sample.xml
will output
```xml
-
+
```
instead of
@@ -293,7 +320,7 @@ Fields with the matching xml-attribute-prefix are assumed to be attributes.
Given a sample.yml file of:
```yaml
cat:
- +name: tiger
+ +@name: tiger
meows: true
```
@@ -314,7 +341,7 @@ Fields with the matching xml-content-name is assumed to be content.
Given a sample.yml file of:
```yaml
cat:
- +name: tiger
+ +@name: tiger
+content: cool
```
@@ -359,11 +386,11 @@ Use the special xml names to add/modify proc instructions and directives.
Given a sample.yml file of:
```yaml
-_procInst_xml: version="1.0"
-_directive_: 'DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" '
++p_xml: version="1.0"
++directive: 'DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" '
apple:
- _procInst_coolioo: version="1.0"
- _directive_: 'CATYPE meow purr puss '
+ +p_coolioo: version="1.0"
+ +directive: 'CATYPE meow purr puss '
b: things
```
diff --git a/pkg/yqlib/encoder_xml.go b/pkg/yqlib/encoder_xml.go
index ecb6a431..4e3dd151 100644
--- a/pkg/yqlib/encoder_xml.go
+++ b/pkg/yqlib/encoder_xml.go
@@ -9,24 +9,19 @@ import (
yaml "gopkg.in/yaml.v3"
)
-var XMLPreferences = xmlPreferences{AttributePrefix: "+", ContentName: "+content", StrictMode: false, UseRawToken: false}
-
type xmlEncoder struct {
- attributePrefix string
- contentName string
- indentString string
- directiveName string
- procInstPrefix string
- writer io.Writer
+ indentString string
+ writer io.Writer
+ prefs xmlPreferences
}
-func NewXMLEncoder(indent int, attributePrefix string, contentName string) Encoder {
+func NewXMLEncoder(indent int, prefs xmlPreferences) Encoder {
var indentString = ""
for index := 0; index < indent; index++ {
indentString = indentString + " "
}
- return &xmlEncoder{attributePrefix, contentName, indentString, "_directive_", "_procInst_", nil}
+ return &xmlEncoder{indentString, nil, prefs}
}
func (e *xmlEncoder) CanHandleAliases() bool {
@@ -97,8 +92,8 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yaml.Node) er
return err
}
- if strings.HasPrefix(key.Value, e.procInstPrefix) {
- name := strings.Replace(key.Value, e.procInstPrefix, "", 1)
+ if strings.HasPrefix(key.Value, e.prefs.ProcInstPrefix) {
+ name := strings.Replace(key.Value, e.prefs.ProcInstPrefix, "", 1)
procInst := xml.ProcInst{Target: name, Inst: []byte(value.Value)}
if err := encoder.EncodeToken(procInst); err != nil {
return err
@@ -106,7 +101,7 @@ func (e *xmlEncoder) encodeTopLevelMap(encoder *xml.Encoder, node *yaml.Node) er
if _, err := e.writer.Write([]byte("\n")); err != nil {
log.Warning("Unable to write newline, skipping: %w", err)
}
- } else if key.Value == e.directiveName {
+ } else if key.Value == e.prefs.DirectiveName {
var directive xml.Directive = []byte(value.Value)
if err := encoder.EncodeToken(directive); err != nil {
return err
@@ -205,6 +200,13 @@ func (e *xmlEncoder) encodeArray(encoder *xml.Encoder, node *yaml.Node, start xm
return e.encodeComment(encoder, footComment(node))
}
+func (e *xmlEncoder) isAttribute(name string) bool {
+ return strings.HasPrefix(name, e.prefs.AttributePrefix) &&
+ name != e.prefs.ContentName &&
+ name != e.prefs.DirectiveName &&
+ !strings.HasPrefix(name, e.prefs.ProcInstPrefix)
+}
+
func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yaml.Node, start xml.StartElement) error {
log.Debug("its a map")
@@ -213,9 +215,9 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yaml.Node, start xml.
key := node.Content[i]
value := node.Content[i+1]
- if strings.HasPrefix(key.Value, e.attributePrefix) && key.Value != e.contentName {
+ if e.isAttribute(key.Value) {
if value.Kind == yaml.ScalarNode {
- attributeName := strings.Replace(key.Value, e.attributePrefix, "", 1)
+ attributeName := strings.Replace(key.Value, e.prefs.AttributePrefix, "", 1)
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: attributeName}, Value: value.Value})
} else {
return fmt.Errorf("cannot use %v as attribute, only scalars are supported", value.Tag)
@@ -237,24 +239,18 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yaml.Node, start xml.
if err != nil {
return err
}
- if strings.HasPrefix(key.Value, e.procInstPrefix) {
- name := strings.Replace(key.Value, e.procInstPrefix, "", 1)
+ if strings.HasPrefix(key.Value, e.prefs.ProcInstPrefix) {
+ name := strings.Replace(key.Value, e.prefs.ProcInstPrefix, "", 1)
procInst := xml.ProcInst{Target: name, Inst: []byte(value.Value)}
if err := encoder.EncodeToken(procInst); err != nil {
return err
}
- } else if key.Value == e.directiveName {
+ } else if key.Value == e.prefs.DirectiveName {
var directive xml.Directive = []byte(value.Value)
if err := encoder.EncodeToken(directive); err != nil {
return err
}
- } else if !strings.HasPrefix(key.Value, e.attributePrefix) && key.Value != e.contentName {
- start := xml.StartElement{Name: xml.Name{Local: key.Value}}
- err := e.doEncode(encoder, value, start)
- if err != nil {
- return err
- }
- } else if key.Value == e.contentName {
+ } else if key.Value == e.prefs.ContentName {
// directly encode the contents
err = e.encodeComment(encoder, headAndLineComment(value))
if err != nil {
@@ -269,6 +265,12 @@ func (e *xmlEncoder) encodeMap(encoder *xml.Encoder, node *yaml.Node, start xml.
if err != nil {
return err
}
+ } else if !e.isAttribute(key.Value) {
+ start := xml.StartElement{Name: xml.Name{Local: key.Value}}
+ err := e.doEncode(encoder, value, start)
+ if err != nil {
+ return err
+ }
}
err = e.encodeComment(encoder, footComment(key))
if err != nil {
diff --git a/pkg/yqlib/lexer_participle.go b/pkg/yqlib/lexer_participle.go
index 170424a7..6cc745cc 100644
--- a/pkg/yqlib/lexer_participle.go
+++ b/pkg/yqlib/lexer_participle.go
@@ -76,7 +76,7 @@ var participleYqRules = []*participleYqRule{
{"Base64d", `@base64d`, decodeOp(Base64InputFormat), 0},
{"Base64", `@base64`, encodeWithIndent(Base64OutputFormat, 0), 0},
- {"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(XMLPreferences.AttributePrefix, XMLPreferences.ContentName, XMLPreferences.StrictMode, XMLPreferences.KeepNamespace, XMLPreferences.UseRawToken), false), 0},
+ {"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(XMLPreferences), false), 0},
{"LoadBase64", `load_?base64`, loadOp(NewBase64Decoder(), false), 0},
diff --git a/pkg/yqlib/lib.go b/pkg/yqlib/lib.go
index e5f42a49..18383383 100644
--- a/pkg/yqlib/lib.go
+++ b/pkg/yqlib/lib.go
@@ -27,8 +27,28 @@ type xmlPreferences struct {
StrictMode bool
KeepNamespace bool
UseRawToken bool
+ ProcInstPrefix string
+ DirectiveName string
+ SkipProcInst bool
+ SkipDirectives bool
}
+func NewDefaultXmlPreferences() xmlPreferences {
+ return xmlPreferences{
+ AttributePrefix: "+@",
+ ContentName: "+content",
+ StrictMode: false,
+ KeepNamespace: true,
+ UseRawToken: false,
+ ProcInstPrefix: "+p_",
+ DirectiveName: "+directive",
+ SkipProcInst: false,
+ SkipDirectives: false,
+ }
+}
+
+var XMLPreferences = NewDefaultXmlPreferences()
+
var log = logging.MustGetLogger("yq-lib")
var PrettyPrintExp = `(... | (select(tag != "!!str"), select(tag == "!!str") | select(test("(?i)^(y|yes|n|no|on|off)$") | not)) ) style=""`
diff --git a/pkg/yqlib/operator_encoder_decoder.go b/pkg/yqlib/operator_encoder_decoder.go
index afb321ef..e8b8a963 100644
--- a/pkg/yqlib/operator_encoder_decoder.go
+++ b/pkg/yqlib/operator_encoder_decoder.go
@@ -23,7 +23,7 @@ func configureEncoder(format PrinterOutputFormat, indent int) Encoder {
case YamlOutputFormat:
return NewYamlEncoder(indent, false, true, true)
case XMLOutputFormat:
- return NewXMLEncoder(indent, XMLPreferences.AttributePrefix, XMLPreferences.ContentName)
+ return NewXMLEncoder(indent, XMLPreferences)
case Base64OutputFormat:
return NewBase64Encoder()
}
@@ -104,12 +104,7 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
case YamlInputFormat:
decoder = NewYamlDecoder()
case XMLInputFormat:
- decoder = NewXMLDecoder(
- XMLPreferences.AttributePrefix,
- XMLPreferences.ContentName,
- XMLPreferences.StrictMode,
- XMLPreferences.KeepNamespace,
- XMLPreferences.UseRawToken)
+ decoder = NewXMLDecoder(XMLPreferences)
case Base64InputFormat:
decoder = NewBase64Decoder()
case PropertiesInputFormat:
diff --git a/pkg/yqlib/xml_test.go b/pkg/yqlib/xml_test.go
index 34b85b15..0c69a24e 100644
--- a/pkg/yqlib/xml_test.go
+++ b/pkg/yqlib/xml_test.go
@@ -58,7 +58,7 @@ cat:
d:
# in d before
z:
- +sweet: cool
+ +@sweet: cool
# in d after
# in y after
# in_cat_after
@@ -98,11 +98,11 @@ cat:
d:
- # in d before
z:
- +sweet: cool
+ +@sweet: cool
# in d after
- # in d2 before
z:
- +sweet: cool2
+ +@sweet: cool2
# in d2 after
# in y after
# in_cat_after
@@ -159,18 +159,18 @@ const inputXMLWithNamespacedAttr = `
`
-const expectedYAMLWithNamespacedAttr = `_procInst_xml: version="1.0"
+const expectedYAMLWithNamespacedAttr = `+p_xml: version="1.0"
map:
- +xmlns: some-namespace
- +xmlns:xsi: some-instance
- +some-instance:schemaLocation: some-url
+ +@xmlns: some-namespace
+ +@xmlns:xsi: some-instance
+ +@some-instance:schemaLocation: some-url
`
-const expectedYAMLWithRawNamespacedAttr = `_procInst_xml: version="1.0"
+const expectedYAMLWithRawNamespacedAttr = `+p_xml: version="1.0"
map:
- +xmlns: some-namespace
- +xmlns:xsi: some-instance
- +xsi:schemaLocation: some-url
+ +@xmlns: some-namespace
+ +@xmlns:xsi: some-instance
+ +@xsi:schemaLocation: some-url
`
const xmlWithCustomDtd = `
@@ -183,18 +183,19 @@ const xmlWithCustomDtd = `
- &writer;©right;
`
-const expectedDtd = `_procInst_xml: version="1.0"
-_directive_: |-
- DOCTYPE root [
-
-
- ]
-root:
- item: '&writer;©right;'
+const expectedDtd = `
+
+
+]>
+
+ - &writer;©right;
+
`
-const expectedSkippedDtd = `root:
- item: '&writer;©right;'
+const expectedSkippedDtd = `
+ - &writer;©right;
+
`
const xmlWithProcInstAndDirectives = `
@@ -206,11 +207,11 @@ const xmlWithProcInstAndDirectives = `
`
-const yamlWithProcInstAndDirectives = `_procInst_xml: version="1.0"
-_directive_: 'DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" '
+const yamlWithProcInstAndDirectives = `+p_xml: version="1.0"
++directive: 'DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" '
apple:
- _procInst_coolioo: version="1.0"
- _directive_: 'CATYPE meow purr puss '
+ +p_coolioo: version="1.0"
+ +directive: 'CATYPE meow purr puss '
b: things
`
@@ -258,13 +259,14 @@ var xmlScenarios = []formatScenario{
subdescription: "DTD entities are processed as directives.",
input: xmlWithCustomDtd,
expected: expectedDtd,
+ scenarioType: "roundtrip",
},
{
- description: "Parse xml: custom dtd",
- subdescription: "DTD entities are processed as directives.",
+ description: "Parse xml: skip custom dtd",
+ subdescription: "DTDs are directives, skip over directives to skip DTDs.",
input: xmlWithCustomDtd,
expected: expectedSkippedDtd,
- scenarioType: "c",
+ scenarioType: "roundtrip-skip-directives",
},
{
description: "Parse xml: with comments",
@@ -360,20 +362,21 @@ var xmlScenarios = []formatScenario{
{
description: "Encode xml: 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: "\n true\n\n",
scenarioType: "encode",
},
{
+ description: "double prefix",
skipDoc: true,
- input: "cat:\n ++name: tiger\n meows: true\n",
- expected: "\n true\n\n",
+ input: "cat:\n +@+@name: tiger\n meows: true\n",
+ expected: "\n true\n\n",
scenarioType: "encode",
},
{
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",
+ input: "cat:\n +@name: tiger\n +content: cool\n",
expected: "cool\n",
scenarioType: "encode",
},
@@ -410,17 +413,23 @@ var xmlScenarios = []formatScenario{
func testXMLScenario(t *testing.T, s formatScenario) {
switch s.scenarioType {
case "", "decode":
- test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder("+", "+content", false, false, false, false, false), NewYamlEncoder(4, false, true, true)), s.description)
+ test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder(XMLPreferences), NewYamlEncoder(4, false, true, true)), s.description)
case "encode":
- test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewYamlDecoder(), NewXMLEncoder(2, "+", "+content")), s.description)
+ test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewYamlDecoder(), NewXMLEncoder(2, XMLPreferences)), s.description)
case "roundtrip":
- test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder("+", "+content", false, false, false, false, false), NewXMLEncoder(2, "+", "+content")), s.description)
+ test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder(XMLPreferences), NewXMLEncoder(2, XMLPreferences)), s.description)
case "decode-keep-ns":
- test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder("+", "+content", false, true, false, false, false), NewYamlEncoder(2, false, true, true)), s.description)
+ prefs := NewDefaultXmlPreferences()
+ prefs.KeepNamespace = true
+ test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder(prefs), NewYamlEncoder(2, false, true, true)), s.description)
case "decode-raw-token":
- test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder("+", "+content", false, true, true, false, false), NewYamlEncoder(2, false, true, true)), s.description)
- case "encode-":
- test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder("+", "+content", false, true, true, true, true), NewYamlEncoder(2, false, true, true)), s.description)
+ prefs := NewDefaultXmlPreferences()
+ prefs.UseRawToken = true
+ test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder(prefs), NewYamlEncoder(2, false, true, true)), s.description)
+ case "roundtrip-skip-directives":
+ prefs := NewDefaultXmlPreferences()
+ prefs.SkipDirectives = true
+ test.AssertResultWithContext(t, s.expected, processFormatScenario(s, NewXMLDecoder(prefs), NewXMLEncoder(2, prefs)), s.description)
default:
panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
}
@@ -443,6 +452,8 @@ func documentXMLScenario(t *testing.T, w *bufio.Writer, i interface{}) {
documentXMLDecodeKeepNsScenario(w, s)
case "decode-raw-token":
documentXMLDecodeKeepNsRawTokenScenario(w, s)
+ case "roundtrip-skip-directives":
+ documentXMLSkipDirectrivesScenario(w, s)
default:
panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
@@ -468,7 +479,7 @@ func documentXMLDecodeScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("```bash\nyq -p=xml '%v' sample.xml\n```\n", expression))
writeOrPanic(w, "will output\n")
- writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder("+", "+content", false, false, false), NewYamlEncoder(2, false, true, true))))
+ writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder(XMLPreferences), NewYamlEncoder(2, false, true, true))))
}
func documentXMLDecodeKeepNsScenario(w *bufio.Writer, s formatScenario) {
@@ -485,11 +496,14 @@ func documentXMLDecodeKeepNsScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, "then\n")
writeOrPanic(w, "```bash\nyq -p=xml -o=xml --xml-keep-namespace '.' sample.xml\n```\n")
writeOrPanic(w, "will output\n")
+ prefs := NewDefaultXmlPreferences()
+ prefs.KeepNamespace = true
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder(prefs), NewXMLEncoder(2, prefs))))
- writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder("+", "+content", false, true, false, false, false), NewXMLEncoder(2, "+", "+content"))))
-
+ prefsWithout := NewDefaultXmlPreferences()
+ prefs.KeepNamespace = false
writeOrPanic(w, "instead of\n")
- writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder("+", "+content", false, false, false, false, false), NewXMLEncoder(2, "+", "+content"))))
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder(prefsWithout), NewXMLEncoder(2, prefsWithout))))
}
func documentXMLDecodeKeepNsRawTokenScenario(w *bufio.Writer, s formatScenario) {
@@ -507,10 +521,16 @@ func documentXMLDecodeKeepNsRawTokenScenario(w *bufio.Writer, s formatScenario)
writeOrPanic(w, "```bash\nyq -p=xml -o=xml --xml-keep-namespace --xml-raw-token '.' sample.xml\n```\n")
writeOrPanic(w, "will output\n")
- writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder("+", "+content", false, true, true, false, false), NewXMLEncoder(2, "+", "+content"))))
+ prefs := NewDefaultXmlPreferences()
+ prefs.KeepNamespace = true
+
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder(prefs), NewXMLEncoder(2, prefs))))
+
+ prefsWithout := NewDefaultXmlPreferences()
+ prefsWithout.KeepNamespace = false
writeOrPanic(w, "instead of\n")
- writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder("+", "+content", false, false, false, false, false), NewXMLEncoder(2, "+", "+content"))))
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder(prefsWithout), NewXMLEncoder(2, prefsWithout))))
}
func documentXMLEncodeScenario(w *bufio.Writer, s formatScenario) {
@@ -528,7 +548,7 @@ func documentXMLEncodeScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, "```bash\nyq -o=xml '.' sample.yml\n```\n")
writeOrPanic(w, "will output\n")
- writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewYamlDecoder(), NewXMLEncoder(2, "+", "+content"))))
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewYamlDecoder(), NewXMLEncoder(2, XMLPreferences))))
}
func documentXMLRoundTripScenario(w *bufio.Writer, s formatScenario) {
@@ -546,7 +566,27 @@ func documentXMLRoundTripScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, "```bash\nyq -p=xml -o=xml '.' sample.xml\n```\n")
writeOrPanic(w, "will output\n")
- writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder("+", "+content", false, false, false, false, false), NewXMLEncoder(2, "+", "+content"))))
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder(XMLPreferences), NewXMLEncoder(2, XMLPreferences))))
+}
+
+func documentXMLSkipDirectrivesScenario(w *bufio.Writer, s formatScenario) {
+ writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))
+
+ if s.subdescription != "" {
+ writeOrPanic(w, s.subdescription)
+ writeOrPanic(w, "\n\n")
+ }
+
+ writeOrPanic(w, "Given a sample.xml file of:\n")
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v\n```\n", s.input))
+
+ writeOrPanic(w, "then\n")
+ writeOrPanic(w, "```bash\nyq -p=xml -o=xml --xml-skip-directives '.' sample.xml\n```\n")
+ writeOrPanic(w, "will output\n")
+ prefs := NewDefaultXmlPreferences()
+ prefs.SkipDirectives = true
+
+ writeOrPanic(w, fmt.Sprintf("```xml\n%v```\n\n", processFormatScenario(s, NewXMLDecoder(prefs), NewXMLEncoder(2, prefs))))
}
func TestXMLScenarios(t *testing.T) {