improvements to XML schema handling

This commit is contained in:
Michael Becker 2021-10-31 14:58:34 -04:00
parent 196d47840c
commit 195b498054
No known key found for this signature in database
GPG Key ID: 98C333A81F18C22C
5 changed files with 145 additions and 2 deletions

View File

@ -0,0 +1,62 @@
//
// XMLSchemas.cs - provides common XML schema definitions used in a wide variety of applications
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2021 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace UniversalEditor.DataFormats.Markup.XML
{
/// <summary>
/// Provides common XML schema definitions used in a wide variety of applications.
/// </summary>
public static class CommonXMLSchemas
{
/// <summary>
/// The /elements/1.1/ namespace was created in 2000 for the RDF representation of the fifteen-element
/// Dublin Core and has been widely used in data for more than twenty years. This namespace corresponds
/// to the original scope of ISO 15836, which was published first in 2003 and last revised in 2017 as
/// ISO 15836-1:2017.
/// </summary>
/// <value>The XML schema for the original Dublin Core namespace.</value>
public static string DublinCore { get; } = "http://purl.org/dc/elements/1.1/";
/// <summary>
/// The /terms/ namespace was originally created in 2001 for identifying new terms coined outside of the
/// original fifteen-element Dublin Core. In 2008, in the context of defining formal semantic constraints
/// for DCMI metadata terms in support of RDF applications, the original fifteen elements themselves were
/// mirrored in the /terms/ namespace. As a result, there exists both a dc:date (http://purl.org/dc/elements/1.1/date)
/// with no formal range and a corresponding dcterms:date (http://purl.org/dc/terms/date) with a formal
/// range of "literal". While these distinctions are significant for creators of RDF applications, most users
/// can safely treat the fifteen parallel properties as equivalent. The most useful properties and classes of
/// DCMI Metadata Terms have now been published as ISO 15836-2:2019 [ISO 15836-2:2019]. While the /elements/1.1/
/// namespace will be supported indefinitely, DCMI gently encourages use of the /terms/ namespace.
/// </summary>
/// <value>The XML schema for the Dublin Core Terms namespace.</value>
public static string DublinCoreTerms { get; } = "http://purl.org/dc/terms/";
/// <summary>
/// The /dcmitype/ namespace was created in 2001 for the DCMI Type Vocabulary, which defines classes for
/// basic types of thing that can be described using DCMI metadata terms.
/// </summary>
/// <value>The XML schema for the Dublin Core DCMI Type namespace.</value>
public static string DublinCoreDCMIType { get; } = "http://purl.org/dc/dcmitype/";
/// <summary>
/// The /dcam/ namespace was created in 2008 for terms used in the description of DCMI metadata terms.
/// </summary>
/// <value>The XML schema for the Dublin Core DCAM namespace.</value>
public static string DublinCoreDCAM { get; } = "http://purl.org/dc/dcam/";
}
}

View File

@ -21,7 +21,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using UniversalEditor.ObjectModels.Markup;
using UniversalEditor.ObjectModels.PropertyList;
@ -116,7 +116,7 @@ namespace UniversalEditor.DataFormats.Markup.XML
if (element is MarkupTagElement)
{
MarkupTagElement tag = element as MarkupTagElement;
tw.Write(indent + Settings.TagBeginChar.ToString() + element.FullName);
tw.Write(indent + Settings.TagBeginChar.ToString() + GetFullName(element));
if (tag.Attributes.Count > 0)
{
tw.Write(" ");
@ -199,6 +199,40 @@ namespace UniversalEditor.DataFormats.Markup.XML
}
}
}
private string GetFullName(MarkupElement element)
{
if (element is MarkupTagElement)
{
if ((element as MarkupTagElement).XMLSchema != null)
{
StringBuilder sb = new StringBuilder();
sb.Append(GetPrefixForXMLSchema(element.ParentObjectModel, (element as MarkupTagElement).XMLSchema));
sb.Append(':');
sb.Append(element.Name);
return sb.ToString();
}
}
return element.FullName;
}
private string GetPrefixForXMLSchema(MarkupObjectModel mom, string xmlSchema)
{
foreach (MarkupElement el in mom.Elements)
{
if (el is MarkupTagElement)
{
foreach (MarkupAttribute att in (el as MarkupTagElement).Attributes)
{
if (att.Namespace == "xmlns" && att.Value == xmlSchema)
return att.Name;
}
break;
}
}
throw new InvalidOperationException(String.Format("xml prefix not found for schema '{0}'", xmlSchema));
}
public void WriteStartDocument()
{
this.WriteStartPreprocessor("xml");

View File

@ -83,10 +83,14 @@ namespace UniversalEditor.ObjectModels.Markup
return basetag;
}
private string _XMLSchema = null;
public string XMLSchema
{
get
{
if (_XMLSchema != null)
return _XMLSchema;
if (this.Namespace == null)
return null;
@ -103,6 +107,33 @@ namespace UniversalEditor.ObjectModels.Markup
return null;
}
set
{
if (this.ParentObjectModel == null)
{
_XMLSchema = value;
return;
}
for (int i = 0; i < this.ParentObjectModel.Elements.Count; i++)
{
MarkupTagElement tagTopLevel = (this.ParentObjectModel.Elements[i] as MarkupTagElement);
if (tagTopLevel == null)
continue;
foreach (MarkupAttribute att in tagTopLevel.Attributes)
{
if (att.Namespace == "xmlns")
{
if (att.Value == value)
{
Namespace = att.Name;
break;
}
}
}
}
}
}
protected override void UpdateParentObjectModel()

View File

@ -29,6 +29,21 @@ namespace UniversalEditor.ObjectModels.Markup
/// </summary>
public class MarkupTagElement : MarkupContainerElement
{
public MarkupTagElement()
{
}
public MarkupTagElement(string fullName, string innerMarkup)
{
FullName = fullName;
Value = innerMarkup;
}
public MarkupTagElement(string schema, string name, string innerMarkup)
{
XMLSchema = schema;
Name = name;
Value = innerMarkup;
}
/// <summary>
/// Combines the attributes and child elements of this <see cref="MarkupTagElement" /> with the given <see cref="MarkupElement" />.
/// </summary>

View File

@ -217,6 +217,7 @@
<Compile Include="DataFormats\Package\OpenDocument\Internal\ManifestXML\ManifestXMLObjectModel.cs" />
<Compile Include="DataFormats\Package\OpenDocument\Internal\ManifestXML\ManifestFileEntry.cs" />
<Compile Include="DataFormats\Package\OpenDocument\Internal\ManifestXML\XMLSchemas.cs" />
<Compile Include="DataFormats\Markup\XML\CommonXMLSchemas.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UniversalEditor.Core\UniversalEditor.Core.csproj">