diff --git a/YamlDotNet.Test/Serialization/SerializationTests.cs b/YamlDotNet.Test/Serialization/SerializationTests.cs
index 823c841a4..48bb0b1cd 100644
--- a/YamlDotNet.Test/Serialization/SerializationTests.cs
+++ b/YamlDotNet.Test/Serialization/SerializationTests.cs
@@ -27,19 +27,17 @@
using System.ComponentModel;
using System.Drawing;
using System.Dynamic;
+using System.Globalization;
using System.IO;
using System.Linq;
-using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;
using Xunit;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
-using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.ObjectFactories;
-using YamlDotNet.Serialization.TypeInspectors;
namespace YamlDotNet.Test.Serialization
{
@@ -810,6 +808,28 @@ public void SerializationOfLongKeysWorksInJson()
writer.ToString().Should().NotContain("?");
}
+
+ [Fact]
+ public void SerializationOfAnchorWorksInJson()
+ {
+ var yamlString = @"
+x: &anchor1
+ z:
+ v: 1
+y:
+ k: *anchor1";
+
+ var deserializer = new DeserializerBuilder().Build();
+ var yamlObject = deserializer.Deserialize(new StringReader(yamlString));
+
+ var serializer = new SerializerBuilder()
+ .JsonCompatible()
+ .Build();
+
+ serializer.Serialize(yamlObject).Trim().Should()
+ .BeEquivalentTo(@"{""x"": {""z"": {""v"": ""1""}}, ""y"": {""k"": {""z"": {""v"": ""1""}}}}");
+ }
+
[Fact]
// Todo: this is actually roundtrip
public void DeserializationOfDefaultsWorkInJson()
diff --git a/YamlDotNet/Core/Emitter.cs b/YamlDotNet/Core/Emitter.cs
index bb314169b..9364f837f 100644
--- a/YamlDotNet/Core/Emitter.cs
+++ b/YamlDotNet/Core/Emitter.cs
@@ -45,6 +45,7 @@ public class Emitter : IEmitter
private readonly int maxSimpleKeyLength;
private readonly bool isCanonical;
+ private readonly bool skipAnchorName;
private readonly int bestIndent;
private readonly int bestWidth;
private EmitterState state;
@@ -140,6 +141,7 @@ public Emitter(TextWriter output, EmitterSettings settings)
this.bestWidth = settings.BestWidth;
this.isCanonical = settings.IsCanonical;
this.maxSimpleKeyLength = settings.MaxSimpleKeyLength;
+ this.skipAnchorName = settings.SkipAnchorName;
this.output = output;
this.outputUsesUnicodeEncoding = IsUnicode(output.Encoding);
@@ -1375,7 +1377,7 @@ private void EmitMappingStart(ParsingEvent evt)
private void ProcessAnchor()
{
- if (anchorData.anchor != null)
+ if (anchorData.anchor != null && !skipAnchorName)
{
WriteIndicator(anchorData.isAlias ? "*" : "&", true, false, false);
WriteAnchor(anchorData.anchor);
diff --git a/YamlDotNet/Core/EmitterSettings.cs b/YamlDotNet/Core/EmitterSettings.cs
index 3451dd13b..7fda68518 100644
--- a/YamlDotNet/Core/EmitterSettings.cs
+++ b/YamlDotNet/Core/EmitterSettings.cs
@@ -1,4 +1,25 @@
-using System;
+// This file is part of YamlDotNet - A .NET library for YAML.
+// Copyright (c) Antoine Aubry and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using System;
namespace YamlDotNet.Core
{
@@ -19,6 +40,11 @@ public sealed class EmitterSettings
///
public bool IsCanonical { get; } = false;
+ ///
+ /// If true, write output without anchor names.
+ ///
+ public bool SkipAnchorName { get; private set; }
+
///
/// The maximum allowed length for simple keys.
///
@@ -33,7 +59,7 @@ public EmitterSettings()
{
}
- public EmitterSettings(int bestIndent, int bestWidth, bool isCanonical, int maxSimpleKeyLength)
+ public EmitterSettings(int bestIndent, int bestWidth, bool isCanonical, int maxSimpleKeyLength, bool skipAnchorName = false)
{
if (bestIndent < 2 || bestIndent > 9)
{
@@ -54,6 +80,7 @@ public EmitterSettings(int bestIndent, int bestWidth, bool isCanonical, int maxS
BestWidth = bestWidth;
IsCanonical = isCanonical;
MaxSimpleKeyLength = maxSimpleKeyLength;
+ SkipAnchorName = skipAnchorName;
}
public EmitterSettings WithBestIndent(int bestIndent)
@@ -95,5 +122,12 @@ public EmitterSettings Canonical()
MaxSimpleKeyLength
);
}
+
+ public EmitterSettings WithoutAnchorName()
+ {
+ SkipAnchorName = true;
+ return this;
+ }
+
}
}
diff --git a/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs b/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs
index 3334821d5..f6a836572 100644
--- a/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs
+++ b/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs
@@ -35,7 +35,7 @@ public JsonEventEmitter(IEventEmitter nextEmitter)
public override void Emit(AliasEventInfo eventInfo, IEmitter emitter)
{
- throw new NotSupportedException("Aliases are not supported in JSON");
+ eventInfo.NeedsExpansion = true;
}
public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
diff --git a/YamlDotNet/Serialization/EventInfo.cs b/YamlDotNet/Serialization/EventInfo.cs
index b1632a40c..ffd19b245 100644
--- a/YamlDotNet/Serialization/EventInfo.cs
+++ b/YamlDotNet/Serialization/EventInfo.cs
@@ -44,6 +44,7 @@ public AliasEventInfo(IObjectDescriptor source, string alias)
}
public string Alias { get; }
+ public bool NeedsExpansion { get; set; }
}
public class ObjectEventInfo : EventInfo
@@ -109,4 +110,4 @@ public SequenceEndEventInfo(IObjectDescriptor source)
{
}
}
-}
\ No newline at end of file
+}
diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs
index 3f7065d59..fd5e663d7 100644
--- a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs
+++ b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs
@@ -45,8 +45,9 @@ public override bool Enter(IObjectDescriptor value, IEmitter context)
var alias = aliasProvider.GetAlias(value.Value);
if (alias != null && !emittedAliases.Add(alias))
{
- eventEmitter.Emit(new AliasEventInfo(value, alias), context);
- return false;
+ var aliasEventInfo = new AliasEventInfo(value, alias);
+ eventEmitter.Emit(aliasEventInfo, context);
+ return aliasEventInfo.NeedsExpansion;
}
}
return base.Enter(value, context);
@@ -74,4 +75,4 @@ public override void VisitScalar(IObjectDescriptor scalar, IEmitter context)
eventEmitter.Emit(scalarInfo, context);
}
}
-}
\ No newline at end of file
+}
diff --git a/YamlDotNet/Serialization/SerializerBuilder.cs b/YamlDotNet/Serialization/SerializerBuilder.cs
index 0cd349454..ace2b181a 100755
--- a/YamlDotNet/Serialization/SerializerBuilder.cs
+++ b/YamlDotNet/Serialization/SerializerBuilder.cs
@@ -286,7 +286,9 @@ public SerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling co
///
public SerializerBuilder JsonCompatible()
{
- this.emitterSettings = this.emitterSettings.WithMaxSimpleKeyLength(int.MaxValue);
+ this.emitterSettings = this.emitterSettings
+ .WithMaxSimpleKeyLength(int.MaxValue)
+ .WithoutAnchorName();
return this
.WithTypeConverter(new GuidConverter(true), w => w.InsteadOf())
@@ -554,7 +556,7 @@ public void SerializeValue(IEmitter emitter, object? value, Type? type)
var preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters);
foreach (var visitor in preProcessingPhaseObjectGraphVisitors)
{
- traversalStrategy.Traverse(graph, visitor, null);
+ traversalStrategy.Traverse(graph, visitor, null!);
}
void nestedObjectSerializer(object? v, Type? t) => SerializeValue(emitter, v, t);
@@ -568,4 +570,4 @@ public void SerializeValue(IEmitter emitter, object? value, Type? type)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/YamlDotNet/Serialization/YamlMember.cs b/YamlDotNet/Serialization/YamlMemberAttribute.cs
similarity index 100%
rename from YamlDotNet/Serialization/YamlMember.cs
rename to YamlDotNet/Serialization/YamlMemberAttribute.cs