Skip to content

Commit

Permalink
Support arbitrary element names via 'xs:any'
Browse files Browse the repository at this point in the history
Those have attribute 'xml.tagName' set to '*'
  • Loading branch information
kwin authored and hboutemy committed Dec 30, 2022
1 parent c5ef5eb commit 1d5831f
Show file tree
Hide file tree
Showing 7 changed files with 22,635 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
public class XsdGenerator
extends AbstractXmlGenerator
{
/**
* Value standing for any element name (used on xml.tagName)
*/
private static final String ANY_NAME = "*";
protected static final String LS = System.getProperty( "line.separator" );

public void generate( Model model, Properties parameters )
Expand Down Expand Up @@ -245,6 +249,15 @@ private void writeComplexTypeDescriptor( XMLWriter w, Model objectModel, ModelCl

if ( !hasContentField )
{
if ( fieldTagName.equals( ANY_NAME ) )
{
w.startElement( "xs:any" );
w.addAttribute( "minOccurs", "0" );
w.addAttribute( "maxOccurs", "unbounded" );
w.addAttribute( "processContents", "skip" );
w.endElement();
continue;
}
w.startElement( "xs:element" );

if ( !enforceMandatoryElements || !field.isRequired() )
Expand Down Expand Up @@ -489,11 +502,19 @@ private void writeListElement( XMLWriter w, XmlFieldMetadata xmlFieldMetadata,

w.startElement( "xs:sequence" );

w.startElement( "xs:element" );
w.addAttribute( "name", valuesTagName );
if ( valuesTagName.equals( ANY_NAME ) )
{
w.startElement( "xs:any" );
w.addAttribute( "processContents", "skip" );
}
else
{
w.startElement( "xs:element" );
w.addAttribute( "type", type );
w.addAttribute( "name", valuesTagName );
}
w.addAttribute( "minOccurs", "0" );
w.addAttribute( "maxOccurs", "unbounded" );
w.addAttribute( "type", type );

w.endElement();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.File;
import java.util.Properties;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
* Check that features.mdo (which tries to be the most complete model) can be checked against XSD generated from
Expand All @@ -61,24 +59,7 @@ public void testXsdGenerator()

modello.generate( model, "xsd", parameters );

/* only available in JAXP 1.3, JDK 5+
SchemaFactory factory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
Schema schema = factory.newSchema( new StreamSource( new File( generatedSources, "features.xsd" ) ) );
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setSchema( schema );
SAXParser parser = spf.newSAXParser();
parser.parse( new InputSource( getClass().getResourceAsStream( "/features.xml" ) ) );
*/

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating( true );
factory.setNamespaceAware( true );
SAXParser saxParser = factory.newSAXParser();
saxParser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema" );
saxParser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaSource",
new File( getOutputDirectory(), "modello-1.4.0.xsd" ) );
SAXParser saxParser = createSaxParserWithSchema( "modello-1.4.0.xsd" );

// first self-test: validate Modello model with xsd generated from it
saxParser.parse( getTestFile( "../../src/main/mdo/modello.mdo" ), new Handler() );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.codehaus.modello.plugin.xsd;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;

import java.io.IOException;
import java.util.Properties;

import org.codehaus.modello.AbstractModelloGeneratorTest;
import org.codehaus.modello.ModelloException;
import org.codehaus.modello.core.ModelloCore;
import org.codehaus.modello.model.Model;
import org.codehaus.modello.model.ModelValidationException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.junit.Test;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

/**
* Test that the <a href="https://github.com/apache/maven/blob/master/maven-plugin-api/src/main/mdo/plugin.mdo">Maven plugin descriptor</a>
* generates an XSD which can validate plugin descriptors (with arbitrary element names below {@code <configuration>}).
* @see <a href="https://github.com/codehaus-plexus/modello/issues/264">Issue 264</a>
*
*/
public class PluginsXsdGeneratorTest
extends AbstractModelloGeneratorTest
{

public PluginsXsdGeneratorTest()
{
super( "plugins" );
}

@Test
public void testWithNameWildcard()
throws ModelloException, ModelValidationException, IOException, ComponentLookupException,
ParserConfigurationException, SAXException
{
ModelloCore modello = (ModelloCore) lookup( ModelloCore.ROLE );

Model model = modello.loadModel( getXmlResourceReader( "/plugin.mdo" ) );

// generate XSD file
Properties parameters = getModelloParameters( "1.0.0" );

modello.generate( model, "xsd", parameters );

SAXParser parser = createSaxParserWithSchema( "plugin-1.0.0.xsd" );
parser.parse( getClass().getResourceAsStream( "/plugin.xml" ), new Handler() );
}

private static class Handler
extends DefaultHandler
{
public void warning( SAXParseException e )
throws SAXException
{
throw e;
}

public void error( SAXParseException e )
throws SAXException
{
throw e;
}
}
}
Loading

0 comments on commit 1d5831f

Please sign in to comment.