[oXygen-user] DocumentTypeCustomRuleMatcher that depends on document child element

Oxygen XML Editor Support support at oxygenxml.com
Wed Apr 11 06:13:24 CDT 2012


Hi Benoît,

One additional thing you should do would be to avoid parsing the 
systemID completely if the root element name does not match at all with 
your type of document type.
In this case, opened XML files which do not belong to your document type 
will not be parsed completely and detection will be faster for them.

This workaround I gave you also has some limitations:

Assume that the author opens an XML document belonging to one of your 
document types and then makes a change in it which makes the XML element 
pertain to your other document type. For example he deletes <proced> and 
inserts <desc>.
Then your DocumentTypeCustomRuleMatcher will get called again but as you 
are reading the XML content from the file and the author has not saved 
the modifications, you will match the document type according to the 
original content and not to the current edited content.

Regards,
Radu

Radu Coravu
<oXygen/>  XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

On 4/11/2012 12:49 PM, Benoit CHERY wrote:
> Thanks, it first did not work but i've seen in debug mode that i had to
> use qName instead of localName.
>
> Regards, Benoît.
>
> Le 11/04/2012 09:20, Oxygen XML Editor Support a écrit :
>> Hi Benoît,
>>
>> Basically Oxygen tries to detect the document type without parsing the
>> entire file, just by looking at the root element (or before the root
>> element, at the document type).
>>
>> But one of the parameters in the interface is "systemID". This is the
>> URL which corresponds to the XML file which is about to be opened.
>> So what you could try to do would be to create a SAX Parser over that
>> systemID and check for that particular XML element, something like:
>>
>>> /**
>>>    * Match XML files which have the<proced>   element inside a<content>   element
>>>    */
>>> public class ProcedCustomRuleMatcher implements DocumentTypeCustomRuleMatcher {
>>>
>>>     private boolean matches = false;
>>>     private Stack<String>   elements = new Stack<String>();
>>>     /**
>>>      * Try to find a<code>DITAArchVersion</code>   attribute in the root attributes.
>>>      *
>>>      * @see ro.sync.ecss.extensions.api.DocumentTypeCustomRuleMatcher#matches(java.lang.String, java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
>>>      */
>>>     public boolean matches(String systemID, String rootNamespace, String rootLocalName,
>>>         String doctypePublicID, Attributes rootAttributes) {
>>>       matches = false;
>>>       try {
>>>         SAXParserFactory.newInstance().newSAXParser().parse(new InputSource(systemID), new DefaultHandler() {
>>>           /**
>>>            * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
>>>            */
>>>           @Override
>>>           public void startElement(String uri, String localName, String qName, Attributes attributes)
>>>               throws SAXException {
>>>             if("proced".equals(localName)) {
>>>               if("content".equals(elements.peek())) {
>>>                 matches = true;
>>>                 //Break the entire parsing early
>>>                 throw new SAXParseException("BROKEN", null);
>>>               }
>>>             }
>>>             elements.push(localName);
>>>           }
>>>           /**
>>>            * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
>>>            */
>>>           @Override
>>>           public void endElement(String uri, String localName, String qName) throws SAXException {
>>>             elements.pop();
>>>           }
>>>         });
>>>       } catch (SAXException e) {
>>>         e.printStackTrace();
>>>       } catch (IOException e) {
>>>         e.printStackTrace();
>>>       } catch (ParserConfigurationException e) {
>>>         e.printStackTrace();
>>>       }
>>>       return matches;
>>>     }
>>>     /**
>>>      * @see ro.sync.ecss.extensions.api.Extension#getDescription()
>>>      */
>>>     @Override
>>>     public String getDescription() {
>>>       return "Match XML files which have the<proced>   element inside a<content>   element";
>>>     }
>>> }
>> You should also probably have a fallback document type which is matched
>> by the XML file even if it does not contain one of those searched XML
>> elements.
>>
>> Regards,
>> Radu
>>
>> Radu Coravu
>> <oXygen/>    XML Editor, Schema Editor and XSLT Editor/Debugger
>> http://www.oxygenxml.com
>>
>> On 4/10/2012 6:13 PM, Benoit CHERY wrote:
>>> Hi,
>>>
>>> I'd like to switch document type depending on an xpath. I thought
>>> DocumentTypeCustomRuleMatcher would do it, but it seems it doesn't
>>> because it only has 5 parameters (which i don't care about) in matches
>>> method.
>>>
>>> My documents look like this :
>>> <doc>
>>> <status/>
>>> <content>
>>> <!-- element here could be either 'proced' or 'desc' -->
>>> </content>
>>> </doc>
>>>
>>> I want to apply different css, schema, toolbar depending on the 'proced'
>>> or 'desc' element, is it possible?
>>> I can't change my document structure because it's normalized.
>>>
>>> Thanks for all.
>>> Benoît.
>>> _______________________________________________
>>> oXygen-user mailing list
>>> oXygen-user at oxygenxml.com
>>> http://www.oxygenxml.com/mailman/listinfo/oxygen-user
>>>
>> _______________________________________________
>> oXygen-user mailing list
>> oXygen-user at oxygenxml.com
>> http://www.oxygenxml.com/mailman/listinfo/oxygen-user
> _______________________________________________
> oXygen-user mailing list
> oXygen-user at oxygenxml.com
> http://www.oxygenxml.com/mailman/listinfo/oxygen-user
>


More information about the oXygen-user mailing list