You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by nicolas de loof <ni...@apache.org> on 2008/05/16 20:53:30 UTC
namespace support in POM.xml ?
Hello,
many thread on this list makes proposal for some changes in the POM.xml
format, to be included in 4.1.0 modelVersion.
Could we use XML namespaces to support progressive enhancements ? Based on
this, proposal for new features could be added to maven, using an
<extension> to support the new schema, without requirement to wait for next
major version to include POM structure changes.
example : considering the recent proposal for profiles enhancements
http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<deactivation>
<os>
<name>Windows 98</name>
</os>
</deactivation>
</profile>
Could be rewritten :
<extensions>
<extension xmlns:profile=
http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>
<groupId>org.apache.maven.proposals</groupId>
<artifactId>profile-enhancements</artifactId>
</extension>
<extensions>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<profile:deactivation>
<profile:os>
<profile:name>Windows 98</profile:name>
</profile:os>
</profile:deactivation>
</profile>
This can be compared with namespace support in Springframework context files
: adding a new custom namespace allow to make the configuration less verbose
or more powerfull, with no requirement to change the base XML model.
Nicolas
Re: namespace support in POM.xml ?
Posted by nicolas de loof <ni...@apache.org>.
The extension would be required to support the new feature behind the
namespace tags.
My idea is to separate the modelVersion (maven-model.jar version in use) and
the POM XML structure, that could use some custom parsing / post-processors,
like the example profile desactivation.
2008/5/18 Bryon Jacob <br...@jacob.net>:
> I wrote a kinda lengthy blog post about doing this sort of thing:
>
>
> http://freedomandbeer.com/posts/extensible-xml-with-xml-namespaces-and-relaxng
>
> RelaxNG is a fantastic language for specifying schemas for XML - the
> grammar notation is very natural to write in. Allowed elements are
> specified using "name classes", and you can perform set arithmetic over
> those classes to achieve some amazing results for extensibility, by
> delegating validation of extension elements to the author of the extensions,
> while retaining the ability to assert the validity of the core document
> structure.
>
> If I understand the problem that you're trying to solve here, it is exactly
> analogous to the example in my blog post. I think you would probably
> structure your xml somewhat differently than below - you define the
> "profile" namespace prefix on the <extension> element, but since the profile
> isn't a child of that element, the declaration doesn't carry through. For
> your goals here, I don't even think the <extension> element buys you
> anything -- what you really want to do, it seems, is change the core Maven
> schema to allow arbitrary extensions to a project's XML, as long as they are
> partitioned into a new namespace - rewriting your example XML:
>
> <project xmlns="http://maven.apache.org/POM/4.0.0">
> ...
> <profile xmlns:profile="
> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation">
>
> <activation>
> <activeByDefault>true</activeByDefault>
> </activation>
> <profile:deactivation>
> <profile:os>
> <profile:name>Windows 98</profile:name>
> <profile:os>
> </profile:deactivation>
> </profile>
> ...
> </project>
>
> Using RelaxNG, you could write the rule for the <profile> element to allow
> any element NOT in the maven namespace to be included:
>
> PROFILE =
> element maven:profile {
> element maven:activation {
> element maven:activeByDefault { xsd:boolean}
> }
> | ANY_EXT_ELEMENT*
> }
> ANY_EXT_ELEMENT =
> element * - maven:* {
> attribute * { text }*,
> ( text* & ANY_EXT_ELEMENT* )*
> }
>
> And then, you could declare a RelaxNG grammar to parse a "project with
> profile enancements" document like:
>
> include "maven.rnc" {
> ANY_EXT_ELEMENT =
> element * - (maven:* | profile:*) {
> attribute * { text }*,
> ( text* & ANY_EXT_ELEMENT* )*
> }
> | DEACTIVATION
> }
> DEACTIVATION =
> element profile:deactivation {
> element profile:os {
> element profile:name { text }
> }
> }
>
> Like I said, there's a much more detailed, and analogous, example at the
> link above. hope this helps!
>
> - Bryon
>
>
>
> On May 16, 2008, at 1:53 PM, nicolas de loof wrote:
>
> Hello,
>>
>> many thread on this list makes proposal for some changes in the POM.xml
>> format, to be included in 4.1.0 modelVersion.
>>
>> Could we use XML namespaces to support progressive enhancements ? Based on
>> this, proposal for new features could be added to maven, using an
>> <extension> to support the new schema, without requirement to wait for
>> next
>> major version to include POM structure changes.
>>
>> example : considering the recent proposal for profiles enhancements
>>
>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>
>> <profile>
>> <activation>
>> <activeByDefault>true</activeByDefault>
>> </activation>
>> <deactivation>
>> <os>
>> <name>Windows 98</name>
>> </os>
>> </deactivation>
>> </profile>
>> Could be rewritten :
>>
>> <extensions>
>> <extension xmlns:profile=
>>
>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>
>>>
>>> <groupId>org.apache.maven.proposals</groupId>
>> <artifactId>profile-enhancements</artifactId>
>> </extension>
>> <extensions>
>>
>> <profile>
>> <activation>
>> <activeByDefault>true</activeByDefault>
>> </activation>
>> <profile:deactivation>
>> <profile:os>
>> <profile:name>Windows 98</profile:name>
>> </profile:os>
>> </profile:deactivation>
>> </profile>
>> This can be compared with namespace support in Springframework context
>> files
>> : adding a new custom namespace allow to make the configuration less
>> verbose
>> or more powerfull, with no requirement to change the base XML model.
>>
>> Nicolas
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>
>
Re: namespace support in POM.xml ?
Posted by Bryon Jacob <br...@jacob.net>.
> In particular, could you compare in detail this relaxng method and
> the similar xml schema approach using substitution groups and
> abstract schema types? (note that the substitution group part of
> this is unnecessary but results in easier to read xml)? After
> studying your blog post I don't see any major differences between
> the relaxng approach and the xml schema approach beyond the
> differences between relaxng and xmlschema. On the other hand this
> is the first time I've seen relaxng.
I haven't written any XSD in a long time, so bear with me a little
bit... and please correct me if there's a better, more concise way to
state things in XSD than I have here, or if there IS a way to do the
things that I claim XSD can't do!
First off, I basically reimplemented the final example from my blog
post using XSD instead of RelaxNG. First, I have a schema for project
files:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://freedomandbeer.com/project/1.0"
elementFormDefault="qualified">
<xs:element name="project">
<xs:complexType>
<xs:all>
<xs:element name="name" type="xs:string"/>
<xs:element name="developers">
<xs:complexType>
<xs:sequence>
<xs:element name="developer" type="xs:string"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="extensions">
<xs:complexType>
<xs:sequence>
<xs:element name="extension">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0"
maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="id"
type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:schema>
and, I have another schema for my "svn" extension:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://freedomandbeer.com/project/ext/svn/1.0"
elementFormDefault="qualified">
<xs:element name="svnRepository">
<xs:complexType>
<xs:sequence>
<xs:element name="url" type="xs:string" minOccurs="1"
maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
which does correctly validate this XML:
<project
xmlns="http://freedomandbeer.com/project/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://freedomandbeer.com/project/1.0
project.xsd
http://freedomandbeer.com/project/ext/svn/1.0 svnext.xsd"
id="myproject">
<name>My Project</name>
<developers>
<developer>Bryon</developer>
<developer>Jasmine</developer>
</developers>
<extensions>
<extension id="source_control">
<svnRepository xmlns="http://freedomandbeer.com/project/ext/svn/1.0
">
<url>http://svn.freedomandbeer.com/myproject/trunk</
url>
</svnRepository>
</extension>
</extensions>
</project>
so, apart from the fact that I think the RelaxNG is MUCH nicer to
read, the basic flavor is implementable fairly easily in XSD.
One place where we've found a need to do something that is just not
possible in XSD is where our "core" product uses multiple namespaces,
and we want to allow "mixing-in" of things that are OUTSIDE of those
namespaces -- in XSD, the rule is "One Schema, One Namespace". We
define a new namespace every time we version our schema, and add the
new schema elements into the new namespace.
If you look at the line in the project XSD where we use an <xs:any>
element to allow for elements outside the schema's namespace to be
included, you'll see that we declared the namespace to be ##other - in
XSD, that means "any element in a namespace other than the one defined
by this schema". Let's call this schema version 1. The problem is
that if we were to add another schema that defined a new "version" of
this schema, and it's own corresponding "version 2" namespace, now the
##other from version 1 can include version 2 elements, and any ##other
references in version 2 can include version 1 elements, which is not
what we intend. There is not (to the best of my knowledge) any way to
"group" namespaces in a meaningful way to say that an element must or
must not come from one of those...
Another thing that is very easy to do in RelaxNG, and hard to do in
XSD, is deal with order and multiplicity in XML docs -- consider a
piece of XML like this:
<car>
<make>Ford</make>
<model>Mustang</model>
<year>2007</year>
<option>Chrome Wheels</option>
<option>CD Changer</option>
<option>Sunroof</option>
</car>
but, maybe you'd like to be able to accept this document as well...
<car>
<make>Ford</make>
<model>Mustang</model>
<option>Chrome Wheels</option>
<option>CD Changer</option>
<option>Sunroof</option>
<year>2007</year>
</car>
in RelaxNG, you can say:
start = CAR
MAKE = element make {text}
MODEL = element model {text}
YEAR = element year {text}
OPTION = element option {text}
CAR = element car { MAKE & MODEL & YEAR & OPTION* }
Which means "a car has exactly one each of make, model, and year
elements, and zero or more option elements - all of which can appear
in any order". Generally, when your XML document represents an object
graph, you don't really care what order child elements appear - just
whether they are there or not. There's no reason why the second
version of the document should be less valid than the first, and
adding this openness makes it easier to interoperate with systems that
speak in the language of your schema.
Trying to get this exact behavior in XSD is hard - there are several
options in XSD that almost do what we want, but not quite...
<xs:all> - this allows for all of the sub-elements to appear in any
order, but each element may only occur 0 or 1 times - not 0 or more
like our option elements.
<xs:sequence> - this is the most commonly used - it allows for each
element to occur any number of times, but the sequence is set, so we
lose the flexibility to move things around.
The best I can do to truly re-create the RelaxNG schema above in XSD is:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://freedomandbeer.com/cars">
<xs:element name="car">
<xs:complexType>
<xs:sequence>
<xs:element name="option" type="xs:string"
minOccurs="0" maxOccurs="unbounded"/>
<xs:choice>
<xs:sequence>
<xs:element name="make" type="xs:string"/>
<xs:element name="option" type="xs:string"
minOccurs="0" maxOccurs="unbounded"/>
<xs:choice>
<xs:sequence>
<xs:element name="model"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="year"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:sequence>
<xs:element name="year"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="model"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
<xs:sequence>
<xs:element name="model" type="xs:string"/>
<xs:element name="option" type="xs:string"
minOccurs="0" maxOccurs="unbounded"/>
<xs:choice>
<xs:sequence>
<xs:element name="make"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="year"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:sequence>
<xs:element name="year"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="make"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
<xs:sequence>
<xs:element name="year" type="xs:string"/>
<xs:element name="option" type="xs:string"
minOccurs="0" maxOccurs="unbounded"/>
<xs:choice>
<xs:sequence>
<xs:element name="make"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="model"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:sequence>
<xs:element name="model"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="make"
type="xs:string"/>
<xs:element name="option"
type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Notice that what we are basically doing is building a DFA that walks
valid documents - because it is a requirement of XSD that what "path"
you go down be deterministic. This means that the size of the schema
will actually be exponential in the number of elements in your
"arbitrary choice group".
Now, to be fair to XSD, if you simply put a "wrapper" element around
all of your options, which is a reasonable thing to do in most cases,
the schema gets MUCH simpler:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://freedomandbeer.com/cars">
<xs:element name="car">
<xs:complexType>
<xs:all>
<xs:element name="make" type="xs:string"/>
<xs:element name="model" type="xs:string"/>
<xs:element name="year" type="xs:string"/>
<xs:element name="options" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="option" minOccurs="0"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
But, I don't really like my choice of schema language telling me that
I can't do something that is perfectly valid XML... Still, it's a
reasonable tradeoff to make if you like the tool support that XSD
offers (which is undeniably better than what exists for RelaxNG...)
Actually, the reason that came to RelaxNG in the first place was
because I had to retroactively design a schema for a legacy system
that had none - and it did something isomorphic to the "car" example
here -- except that it had much more than the make/model/year/option
mix to deal with -- the XSD would have had thousands of paths and
would have been totally impossible to maintain.
Anyways - sorry if this has devolved into a generic "why RelaxNG is
better than XSD" argument... I do think that's very true - but that's
not the intention here. I think that RelaxNG provides a much more
robust way than XSD of dealing with documents that need a high degree
of extensibility -- and it gives you the freedom to define your schema
in the most natural way for document authors and consumers to
understand, without your schema language getting in the way.
Additionally, RelaxNG schemas are VERY readable, and provide excellent
documentation that virtually anyone can quickly grok - I don't find
the same to be true with XSD...
Re: namespace support in POM.xml ?
Posted by Bryon Jacob <br...@jacob.net>.
>
> Are there any tools like jaxb that work with relaxng?
To the best of my knowledge, there are not (for java). The language
"binding" frameworks for RelaxNG that I have seen generally involve
annotating the RelaxNG grammar with explicit hints about how to map
schema elements to object model elements in the target language...
Where I work, we have a proprietary XML binding framework (yes, I
know, another one...) that uses RelaxNG, and I have preliminary
authorization to release it as an open-source project on Codehaus -- I
just need to get the final sign-off from the lawyers, and I'll be
sharing it out. (and we do have a track record of doing this -- the
same company has allowed us to release Atomserver - http://atomserver.codehaus.org
- so, I believe that we truly will be releasing this in weeks not
months, if there is interest...)
Anyways, the technique that we use for this framework is a little
different than most other frameworks out there - I'll outline it
quickly here:
the primary way you define your object model is by writing java
interfaces - they should use the standard JavaBeans conventions for
getters/setters. You can annotate the getters with annotations that
specify how the property should be handled in XML:
public interface Car {
@Attribute
Long getId();
void setId(Long id);
@Element
String getMake();
void setMake(String make);
@Element
String getModel();
void setModel(String model);
@CollectionElement(itemName="option", occurs = Occurs.ANY)
List<String> getOptions();
void setOptions(List<String> options);
}
you put all of the interfaces for one object model into the same java
package, and then you run the IBeans (short for interface-beans)
compiler on the package -- it generates an "implementation" package
that contains implementations for all of the bean interfaces (trivial
boilerplate code...) and a STAX marshaller/unmarshaller (using
woodstox under the covers) for each type. The compiler also generates
a RelaxNG grammar for the object model, that follows the same rules
laid out by the annotations.
At compile-time, you are only dependent on the IBeans runtime library
and your interfaces - NOT the generated package (you need to know the
NAME of the package) - so, for IDE support, it's great - you can truly
treat the generated code as an artifact of your build process:
IBeans ibeans = new IBeans("com.freedomandbeer.cars.impl");
Car car = ibeans.newInstance(Car.class);
car.setMake("Ford");
car.setModel("Mustang");
car.setOptions(Arrays.asList("chrome", "cd changer"));
StringWriter writer = new StringWriter();
ibeans.marshallDocument(car, Car.class, writer);
System.out.println(writer.toString());
Currently, the compiler outputs java source that must then be compiled
and put into the classpath at runtime -- one of the big features I'd
like to do in the next major release is to give the IBeans class a
custom classloader, and have it generate the bean implementations and
XML marshalling/unmarshalling code on the fly - so there IS no jar of
implementation classes... the only thing on the main application
classpath is the ibeans runtime and the compiled, annotated
interfaces...
FWIW - we built this framework because we really didn't find that any
of the existing binding frameworks out there quite supported all of
our needs, which were:
1) we have a lot of different schemas to maintain, and they evolve
fairly rapidly, so minimalizing the amount of code required to define
the schemas and their binding to objects was a must
2) most of these schemas define APIs to web services, and we don't
have total control over the upgrade paths of clients, so we needed
very flexible formats that allow us to roll out new features for some
clients, without breaking clients who aren't ready to move
3) these systems get a TON of traffic, so XML marshalling/
unmarshalling had to be as fast as possible
with IBeans, we only maintain ONE representation of the object model
(the annotated interfaces) and there is no separate binding
representation. By using STAX and RelaxNG, we can easily have very
open formats that are tolerant of clients changing the order of
things, etc, while still validating the things that we really care
about. Finally, by doing our unmarshalling of XML with a custom-
crafted STAX parser for each type, we know that we can both parse and
validate any document in a single pass through the parser.
anyways - that's probably enough of this for the maven list! If
there's interest in IBeans for potentially being used by maven to
manage the POMs, a post or two to that effect on this list might help
me get the legal deal expedited at work. If people have interest in
IBeans in general, email me offline and I'll let you know when I get
the package out in the wild. thanks!
- Bryon
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org
Re: namespace support in POM.xml ?
Posted by Jason van Zyl <ja...@maven.org>.
On 21-May-08, at 8:07 AM, David Jencks wrote:
> In particular, could you compare in detail this relaxng method and
> the similar xml schema approach using substitution groups and
> abstract schema types? (note that the substitution group part of
> this is unnecessary but results in easier to read xml)? After
> studying your blog post I don't see any major differences between
> the relaxng approach and the xml schema approach beyond the
> differences between relaxng and xmlschema. On the other hand this
> is the first time I've seen relaxng.
>
I find the grammar way easier to read.
> Are there any tools like jaxb that work with relaxng?
>
> thanks
> david jencks
>
> On May 21, 2008, at 10:56 AM, Jason van Zyl wrote:
>
>> Bryon,
>>
>> How would you compare this with a method like this using XML
>> Schema. I'm not a huge fan of XSD, but there is a lot of tooling
>> for XSD especially in IDEs and that would be something we have to
>> consider. Do you actually use this method you describe in a
>> production system, or just a thought experiment?
>>
>> On 18-May-08, at 2:49 PM, Bryon Jacob wrote:
>>
>>> I wrote a kinda lengthy blog post about doing this sort of thing:
>>>
>>> http://freedomandbeer.com/posts/extensible-xml-with-xml-namespaces-and-relaxng
>>>
>>> RelaxNG is a fantastic language for specifying schemas for XML -
>>> the grammar notation is very natural to write in. Allowed
>>> elements are specified using "name classes", and you can perform
>>> set arithmetic over those classes to achieve some amazing results
>>> for extensibility, by delegating validation of extension elements
>>> to the author of the extensions, while retaining the ability to
>>> assert the validity of the core document structure.
>>>
>>> If I understand the problem that you're trying to solve here, it
>>> is exactly analogous to the example in my blog post. I think you
>>> would probably structure your xml somewhat differently than below
>>> - you define the "profile" namespace prefix on the <extension>
>>> element, but since the profile isn't a child of that element, the
>>> declaration doesn't carry through. For your goals here, I don't
>>> even think the <extension> element buys you anything -- what you
>>> really want to do, it seems, is change the core Maven schema to
>>> allow arbitrary extensions to a project's XML, as long as they are
>>> partitioned into a new namespace - rewriting your example XML:
>>>
>>> <project xmlns="http://maven.apache.org/POM/4.0.0">
>>> ...
>>> <profile xmlns:profile="http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>> ">
>>> <activation>
>>> <activeByDefault>true</activeByDefault>
>>> </activation>
>>> <profile:deactivation>
>>> <profile:os>
>>> <profile:name>Windows 98</profile:name>
>>> <profile:os>
>>> </profile:deactivation>
>>> </profile>
>>> ...
>>> </project>
>>>
>>> Using RelaxNG, you could write the rule for the <profile> element
>>> to allow any element NOT in the maven namespace to be included:
>>>
>>> PROFILE =
>>> element maven:profile {
>>> element maven:activation {
>>> element maven:activeByDefault { xsd:boolean}
>>> }
>>> | ANY_EXT_ELEMENT*
>>> }
>>> ANY_EXT_ELEMENT =
>>> element * - maven:* {
>>> attribute * { text }*,
>>> ( text* & ANY_EXT_ELEMENT* )*
>>> }
>>>
>>> And then, you could declare a RelaxNG grammar to parse a "project
>>> with profile enancements" document like:
>>>
>>> include "maven.rnc" {
>>> ANY_EXT_ELEMENT =
>>> element * - (maven:* | profile:*) {
>>> attribute * { text }*,
>>> ( text* & ANY_EXT_ELEMENT* )*
>>> }
>>> | DEACTIVATION
>>> }
>>> DEACTIVATION =
>>> element profile:deactivation {
>>> element profile:os {
>>> element profile:name { text }
>>> }
>>> }
>>>
>>> Like I said, there's a much more detailed, and analogous, example
>>> at the link above. hope this helps!
>>>
>>> - Bryon
>>>
>>>
>>> On May 16, 2008, at 1:53 PM, nicolas de loof wrote:
>>>
>>>> Hello,
>>>>
>>>> many thread on this list makes proposal for some changes in the
>>>> POM.xml
>>>> format, to be included in 4.1.0 modelVersion.
>>>>
>>>> Could we use XML namespaces to support progressive enhancements ?
>>>> Based on
>>>> this, proposal for new features could be added to maven, using an
>>>> <extension> to support the new schema, without requirement to
>>>> wait for next
>>>> major version to include POM structure changes.
>>>>
>>>> example : considering the recent proposal for profiles enhancements
>>>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>>>
>>>> <profile>
>>>> <activation>
>>>> <activeByDefault>true</activeByDefault>
>>>> </activation>
>>>> <deactivation>
>>>> <os>
>>>> <name>Windows 98</name>
>>>> </os>
>>>> </deactivation>
>>>> </profile>
>>>> Could be rewritten :
>>>>
>>>> <extensions>
>>>> <extension xmlns:profile=
>>>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>>>>
>>>> <groupId>org.apache.maven.proposals</groupId>
>>>> <artifactId>profile-enhancements</artifactId>
>>>> </extension>
>>>> <extensions>
>>>>
>>>> <profile>
>>>> <activation>
>>>> <activeByDefault>true</activeByDefault>
>>>> </activation>
>>>> <profile:deactivation>
>>>> <profile:os>
>>>> <profile:name>Windows 98</profile:name>
>>>> </profile:os>
>>>> </profile:deactivation>
>>>> </profile>
>>>> This can be compared with namespace support in Springframework
>>>> context files
>>>> : adding a new custom namespace allow to make the configuration
>>>> less verbose
>>>> or more powerfull, with no requirement to change the base XML
>>>> model.
>>>>
>>>> Nicolas
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
>>> For additional commands, e-mail: dev-help@maven.apache.org
>>>
>>
>> Thanks,
>>
>> Jason
>>
>> ----------------------------------------------------------
>> Jason van Zyl
>> Founder, Apache Maven
>> jason at sonatype dot com
>> ----------------------------------------------------------
>>
>> What matters is not ideas, but the people who have them. Good
>> people can fix bad ideas, but good ideas can't save bad people.
>>
>> -- Paul Graham
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
>> For additional commands, e-mail: dev-help@maven.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>
Thanks,
Jason
----------------------------------------------------------
Jason van Zyl
Founder, Apache Maven
jason at sonatype dot com
----------------------------------------------------------
the course of true love never did run smooth ...
-- Shakespeare
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org
Re: namespace support in POM.xml ?
Posted by David Jencks <da...@yahoo.com>.
In particular, could you compare in detail this relaxng method and the
similar xml schema approach using substitution groups and abstract
schema types? (note that the substitution group part of this is
unnecessary but results in easier to read xml)? After studying your
blog post I don't see any major differences between the relaxng
approach and the xml schema approach beyond the differences between
relaxng and xmlschema. On the other hand this is the first time I've
seen relaxng.
Are there any tools like jaxb that work with relaxng?
thanks
david jencks
On May 21, 2008, at 10:56 AM, Jason van Zyl wrote:
> Bryon,
>
> How would you compare this with a method like this using XML Schema.
> I'm not a huge fan of XSD, but there is a lot of tooling for XSD
> especially in IDEs and that would be something we have to consider.
> Do you actually use this method you describe in a production system,
> or just a thought experiment?
>
> On 18-May-08, at 2:49 PM, Bryon Jacob wrote:
>
>> I wrote a kinda lengthy blog post about doing this sort of thing:
>>
>> http://freedomandbeer.com/posts/extensible-xml-with-xml-namespaces-and-relaxng
>>
>> RelaxNG is a fantastic language for specifying schemas for XML -
>> the grammar notation is very natural to write in. Allowed elements
>> are specified using "name classes", and you can perform set
>> arithmetic over those classes to achieve some amazing results for
>> extensibility, by delegating validation of extension elements to
>> the author of the extensions, while retaining the ability to assert
>> the validity of the core document structure.
>>
>> If I understand the problem that you're trying to solve here, it is
>> exactly analogous to the example in my blog post. I think you
>> would probably structure your xml somewhat differently than below -
>> you define the "profile" namespace prefix on the <extension>
>> element, but since the profile isn't a child of that element, the
>> declaration doesn't carry through. For your goals here, I don't
>> even think the <extension> element buys you anything -- what you
>> really want to do, it seems, is change the core Maven schema to
>> allow arbitrary extensions to a project's XML, as long as they are
>> partitioned into a new namespace - rewriting your example XML:
>>
>> <project xmlns="http://maven.apache.org/POM/4.0.0">
>> ...
>> <profile xmlns:profile="http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>> ">
>> <activation>
>> <activeByDefault>true</activeByDefault>
>> </activation>
>> <profile:deactivation>
>> <profile:os>
>> <profile:name>Windows 98</profile:name>
>> <profile:os>
>> </profile:deactivation>
>> </profile>
>> ...
>> </project>
>>
>> Using RelaxNG, you could write the rule for the <profile> element
>> to allow any element NOT in the maven namespace to be included:
>>
>> PROFILE =
>> element maven:profile {
>> element maven:activation {
>> element maven:activeByDefault { xsd:boolean}
>> }
>> | ANY_EXT_ELEMENT*
>> }
>> ANY_EXT_ELEMENT =
>> element * - maven:* {
>> attribute * { text }*,
>> ( text* & ANY_EXT_ELEMENT* )*
>> }
>>
>> And then, you could declare a RelaxNG grammar to parse a "project
>> with profile enancements" document like:
>>
>> include "maven.rnc" {
>> ANY_EXT_ELEMENT =
>> element * - (maven:* | profile:*) {
>> attribute * { text }*,
>> ( text* & ANY_EXT_ELEMENT* )*
>> }
>> | DEACTIVATION
>> }
>> DEACTIVATION =
>> element profile:deactivation {
>> element profile:os {
>> element profile:name { text }
>> }
>> }
>>
>> Like I said, there's a much more detailed, and analogous, example
>> at the link above. hope this helps!
>>
>> - Bryon
>>
>>
>> On May 16, 2008, at 1:53 PM, nicolas de loof wrote:
>>
>>> Hello,
>>>
>>> many thread on this list makes proposal for some changes in the
>>> POM.xml
>>> format, to be included in 4.1.0 modelVersion.
>>>
>>> Could we use XML namespaces to support progressive enhancements ?
>>> Based on
>>> this, proposal for new features could be added to maven, using an
>>> <extension> to support the new schema, without requirement to wait
>>> for next
>>> major version to include POM structure changes.
>>>
>>> example : considering the recent proposal for profiles enhancements
>>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>>
>>> <profile>
>>> <activation>
>>> <activeByDefault>true</activeByDefault>
>>> </activation>
>>> <deactivation>
>>> <os>
>>> <name>Windows 98</name>
>>> </os>
>>> </deactivation>
>>> </profile>
>>> Could be rewritten :
>>>
>>> <extensions>
>>> <extension xmlns:profile=
>>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>>>
>>> <groupId>org.apache.maven.proposals</groupId>
>>> <artifactId>profile-enhancements</artifactId>
>>> </extension>
>>> <extensions>
>>>
>>> <profile>
>>> <activation>
>>> <activeByDefault>true</activeByDefault>
>>> </activation>
>>> <profile:deactivation>
>>> <profile:os>
>>> <profile:name>Windows 98</profile:name>
>>> </profile:os>
>>> </profile:deactivation>
>>> </profile>
>>> This can be compared with namespace support in Springframework
>>> context files
>>> : adding a new custom namespace allow to make the configuration
>>> less verbose
>>> or more powerfull, with no requirement to change the base XML model.
>>>
>>> Nicolas
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
>> For additional commands, e-mail: dev-help@maven.apache.org
>>
>
> Thanks,
>
> Jason
>
> ----------------------------------------------------------
> Jason van Zyl
> Founder, Apache Maven
> jason at sonatype dot com
> ----------------------------------------------------------
>
> What matters is not ideas, but the people who have them. Good people
> can fix bad ideas, but good ideas can't save bad people.
>
> -- Paul Graham
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org
Re: namespace support in POM.xml ?
Posted by Bryon Jacob <br...@jacob.net>.
On May 21, 2008, at 9:56 AM, Jason van Zyl wrote:
> Bryon,
>
> How would you compare this with a method like this using XML Schema.
> I'm not a huge fan of XSD, but there is a lot of tooling for XSD
> especially in IDEs and that would be something we have to consider.
> Do you actually use this method you describe in a production system,
> or just a thought experiment?
>
We use this method to define XML schemas for all of our web services
at our very web-service oriented company...
We chose to move to RelaxNG to solve a particular problem with our XML
service interfaces - we wanted to have a guarantee that clients and
servers on all "minor versions" of a service within a "major version"
were completely interoperable. So, if your client is using service
Foo, and you have version 1.x of the schema, you can access a server
running any version 1.y of the service, and you will be able to
validate the correctness of any elements up to and including 1.x,
while quietly ignoring things outside of that scope.
We also wanted to allow for arbitrary XML that was outside the scope
of the "core" elements to be "mixed-in" freely within the document.
It turns out that solving these two problems really amounts to the
same thing. First, we declare a brand new RelaxNG schema when we move
"major versions", and within those docs, a new namespace for each
"minor version".
For example, if you had the 2.2 version of one of our service schemas,
it would look like:
default namespace = "http://freedomandbeer.com/service/v2/rev0"
namespace v2_0 = "http://freedomandbeer.com/service/v2/rev0"
namespace v2_1 = "http://freedomandbeer.com/service/v2/rev1"
namespace v2_2 = "http://freedomandbeer.com/service/v2/rev2"
Then, we create an ANY_OTHER_ELEMENT declaration, similar to the one
in my blog post, that excludes anything in any of our declared
namespaces:
ANY_OTHER_ELEMENT =
element * - (v2_0:* | v2_1:* | v2_2:*) {
attribute * { text }*,
( text* & ANY_OTHER_ELEMENT* )*
}
And finally, we declare ALL of our elements to "mix-in" any number of
ANY_OTHER_ELEMENTs into their body:
element person {
attribute id { text },
(
element firstName { text } &
element lastName { text } &
element v2_2:ssn { text } &
ANY_OTHER_ELEMENT*
)*
}
Note that because of the "default" namespace declaration, the "person"
element, and its "firstName" and "lastName" children are in the v2_0
namespace, whereas the "ssn" element is in the v2_2 namespace.
it's easy to see how this allows arbitrary "mix-ins" from unrelated
namespaces. How this handles the version compatibility problem is a
little more subtle, but very related to the mixins. Let's look at the
case of someone who has the 2.1 version of our schema - their document
doesn't declare the v2_2 namespace, and their ANY_OTHER_ELEMENT looks
like:
ANY_OTHER_ELEMENT =
element * - (v2_0:* | v2_1:*) {
attribute * { text }*,
( text* & ANY_OTHER_ELEMENT* )*
}
their "person" declaration looks like:
element person {
attribute id { text },
(
element firstName { text } &
element lastName { text } &
ANY_OTHER_ELEMENT*
)*
}
If we had a person, defined as:
<person xmlns="http://freedomandbeer.com/service/v2/rev0">
<firstName>Monty</firstName>
<lastName>Burns</lastName>
<ssn xmlns="http://freedomandbeer.com/service/v2/
rev2">000-00-0002</ssn>
</person>
It would validate fine against both schemas -- in the 2.2 version, the
"ssn" element is validated to be correct. In the 2.1 version, the 2.2
version of the namespace is just another ANY_OTHER_ELEMENT, so it is
ignored. Note that this is only BACKWARDS compatible -- if you are
validating against the 2.2 version of the schema, the "ssn" element is
required, so it must be there. Achieving bi-directional compatibility
is easy enough by just following the rule that any elements that are
ADDED to the schema are "optional". If you truly need to add
something that absolutely must be "required", then (in our world), you
must make a major version of your API...
I think this technique could be useful in defining schemas for things
like Maven's POM -- it allows you to version your schema regularly (as
often as every new maven release). It allows projects built with
maven to utilize the very newest elements without worrying that they
will break compatibility with people on a previous version of maven
(of course, this is also dictated by the semantics of the system - if
my build requires a feature from the 2.1.2 version of maven to build,
then someone with 2.1.1 is just dead in the water... but if the
things added to the schema are "optional" in some sense, then you have
a situation where systems that are aware of it can validate it, and
systems that aren't can safely skip it)
The real application of this technique to something like maven,
though, is in doing something like the example in my blog post --
adding extensions as "mix-ins" that can be defined in their own
schema, and put where the core application can find them.
As to your other question -- the biggest con to using RelaxNG is the
lack of tool support. The JING library (http://www.thaiopensource.com/relaxng/jing.html
), written by longtime XML guru James Clark, is a good library for
RelaxNG validation in java. The oXygen editor (http://www.oxygenxml.com/
) has great support for RelaxNG - but it's not free, and it's not all
that cheap either :(.
Re: namespace support in POM.xml ?
Posted by Jason van Zyl <ja...@maven.org>.
Bryon,
How would you compare this with a method like this using XML Schema.
I'm not a huge fan of XSD, but there is a lot of tooling for XSD
especially in IDEs and that would be something we have to consider. Do
you actually use this method you describe in a production system, or
just a thought experiment?
On 18-May-08, at 2:49 PM, Bryon Jacob wrote:
> I wrote a kinda lengthy blog post about doing this sort of thing:
>
> http://freedomandbeer.com/posts/extensible-xml-with-xml-namespaces-and-relaxng
>
> RelaxNG is a fantastic language for specifying schemas for XML - the
> grammar notation is very natural to write in. Allowed elements are
> specified using "name classes", and you can perform set arithmetic
> over those classes to achieve some amazing results for
> extensibility, by delegating validation of extension elements to the
> author of the extensions, while retaining the ability to assert the
> validity of the core document structure.
>
> If I understand the problem that you're trying to solve here, it is
> exactly analogous to the example in my blog post. I think you would
> probably structure your xml somewhat differently than below - you
> define the "profile" namespace prefix on the <extension> element,
> but since the profile isn't a child of that element, the declaration
> doesn't carry through. For your goals here, I don't even think the
> <extension> element buys you anything -- what you really want to do,
> it seems, is change the core Maven schema to allow arbitrary
> extensions to a project's XML, as long as they are partitioned into
> a new namespace - rewriting your example XML:
>
> <project xmlns="http://maven.apache.org/POM/4.0.0">
> ...
> <profile xmlns:profile="http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
> ">
> <activation>
> <activeByDefault>true</activeByDefault>
> </activation>
> <profile:deactivation>
> <profile:os>
> <profile:name>Windows 98</profile:name>
> <profile:os>
> </profile:deactivation>
> </profile>
> ...
> </project>
>
> Using RelaxNG, you could write the rule for the <profile> element to
> allow any element NOT in the maven namespace to be included:
>
> PROFILE =
> element maven:profile {
> element maven:activation {
> element maven:activeByDefault { xsd:boolean}
> }
> | ANY_EXT_ELEMENT*
> }
> ANY_EXT_ELEMENT =
> element * - maven:* {
> attribute * { text }*,
> ( text* & ANY_EXT_ELEMENT* )*
> }
>
> And then, you could declare a RelaxNG grammar to parse a "project
> with profile enancements" document like:
>
> include "maven.rnc" {
> ANY_EXT_ELEMENT =
> element * - (maven:* | profile:*) {
> attribute * { text }*,
> ( text* & ANY_EXT_ELEMENT* )*
> }
> | DEACTIVATION
> }
> DEACTIVATION =
> element profile:deactivation {
> element profile:os {
> element profile:name { text }
> }
> }
>
> Like I said, there's a much more detailed, and analogous, example at
> the link above. hope this helps!
>
> - Bryon
>
>
> On May 16, 2008, at 1:53 PM, nicolas de loof wrote:
>
>> Hello,
>>
>> many thread on this list makes proposal for some changes in the
>> POM.xml
>> format, to be included in 4.1.0 modelVersion.
>>
>> Could we use XML namespaces to support progressive enhancements ?
>> Based on
>> this, proposal for new features could be added to maven, using an
>> <extension> to support the new schema, without requirement to wait
>> for next
>> major version to include POM structure changes.
>>
>> example : considering the recent proposal for profiles enhancements
>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>
>> <profile>
>> <activation>
>> <activeByDefault>true</activeByDefault>
>> </activation>
>> <deactivation>
>> <os>
>> <name>Windows 98</name>
>> </os>
>> </deactivation>
>> </profile>
>> Could be rewritten :
>>
>> <extensions>
>> <extension xmlns:profile=
>> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>>
>> <groupId>org.apache.maven.proposals</groupId>
>> <artifactId>profile-enhancements</artifactId>
>> </extension>
>> <extensions>
>>
>> <profile>
>> <activation>
>> <activeByDefault>true</activeByDefault>
>> </activation>
>> <profile:deactivation>
>> <profile:os>
>> <profile:name>Windows 98</profile:name>
>> </profile:os>
>> </profile:deactivation>
>> </profile>
>> This can be compared with namespace support in Springframework
>> context files
>> : adding a new custom namespace allow to make the configuration
>> less verbose
>> or more powerfull, with no requirement to change the base XML model.
>>
>> Nicolas
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>
Thanks,
Jason
----------------------------------------------------------
Jason van Zyl
Founder, Apache Maven
jason at sonatype dot com
----------------------------------------------------------
What matters is not ideas, but the people who have them. Good people
can fix bad ideas, but good ideas can't save bad people.
-- Paul Graham
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org
Re: namespace support in POM.xml ?
Posted by Bryon Jacob <br...@jacob.net>.
I wrote a kinda lengthy blog post about doing this sort of thing:
http://freedomandbeer.com/posts/extensible-xml-with-xml-namespaces-and-relaxng
RelaxNG is a fantastic language for specifying schemas for XML - the
grammar notation is very natural to write in. Allowed elements are
specified using "name classes", and you can perform set arithmetic
over those classes to achieve some amazing results for extensibility,
by delegating validation of extension elements to the author of the
extensions, while retaining the ability to assert the validity of the
core document structure.
If I understand the problem that you're trying to solve here, it is
exactly analogous to the example in my blog post. I think you would
probably structure your xml somewhat differently than below - you
define the "profile" namespace prefix on the <extension> element, but
since the profile isn't a child of that element, the declaration
doesn't carry through. For your goals here, I don't even think the
<extension> element buys you anything -- what you really want to do,
it seems, is change the core Maven schema to allow arbitrary
extensions to a project's XML, as long as they are partitioned into a
new namespace - rewriting your example XML:
<project xmlns="http://maven.apache.org/POM/4.0.0">
...
<profile xmlns:profile="http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
">
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<profile:deactivation>
<profile:os>
<profile:name>Windows 98</profile:name>
<profile:os>
</profile:deactivation>
</profile>
...
</project>
Using RelaxNG, you could write the rule for the <profile> element to
allow any element NOT in the maven namespace to be included:
PROFILE =
element maven:profile {
element maven:activation {
element maven:activeByDefault { xsd:boolean}
}
| ANY_EXT_ELEMENT*
}
ANY_EXT_ELEMENT =
element * - maven:* {
attribute * { text }*,
( text* & ANY_EXT_ELEMENT* )*
}
And then, you could declare a RelaxNG grammar to parse a "project with
profile enancements" document like:
include "maven.rnc" {
ANY_EXT_ELEMENT =
element * - (maven:* | profile:*) {
attribute * { text }*,
( text* & ANY_EXT_ELEMENT* )*
}
| DEACTIVATION
}
DEACTIVATION =
element profile:deactivation {
element profile:os {
element profile:name { text }
}
}
Like I said, there's a much more detailed, and analogous, example at
the link above. hope this helps!
- Bryon
On May 16, 2008, at 1:53 PM, nicolas de loof wrote:
> Hello,
>
> many thread on this list makes proposal for some changes in the
> POM.xml
> format, to be included in 4.1.0 modelVersion.
>
> Could we use XML namespaces to support progressive enhancements ?
> Based on
> this, proposal for new features could be added to maven, using an
> <extension> to support the new schema, without requirement to wait
> for next
> major version to include POM structure changes.
>
> example : considering the recent proposal for profiles enhancements
> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>
> <profile>
> <activation>
> <activeByDefault>true</activeByDefault>
> </activation>
> <deactivation>
> <os>
> <name>Windows 98</name>
> </os>
> </deactivation>
> </profile>
> Could be rewritten :
>
> <extensions>
> <extension xmlns:profile=
> http://docs.codehaus.org/display/MAVENUSER/Improvements+to+Profile+Activation+Deactivation
>>
> <groupId>org.apache.maven.proposals</groupId>
> <artifactId>profile-enhancements</artifactId>
> </extension>
> <extensions>
>
> <profile>
> <activation>
> <activeByDefault>true</activeByDefault>
> </activation>
> <profile:deactivation>
> <profile:os>
> <profile:name>Windows 98</profile:name>
> </profile:os>
> </profile:deactivation>
> </profile>
> This can be compared with namespace support in Springframework
> context files
> : adding a new custom namespace allow to make the configuration less
> verbose
> or more powerfull, with no requirement to change the base XML model.
>
> Nicolas
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org