Commons Digester
  1. Commons Digester
  2. DIGESTER-105

[digester] Need to process [attribute id="name"]somename[/attribute]

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.6
    • Fix Version/s: 3.0
    • Labels:
      None
    • Environment:

      Operating System: other
      Platform: Other

      Description

      It is reasonably common to encounter xml like
      <person>
      <attribute id='name'>somename</attribute>
      <attribute id='age'>99</attribute>
      ..
      </person>

      Currently there is no built-in rule to support this in Digester:
      BeanPropertySetterRule supports <name>somename</name>
      SetPropertyRule supports <attribute id='name' value='somename'/>.
      SetPropertiesRule supports <attribute name='somename'/>
      but nothing supports the first syntax listed above.

        Activity

        Hide
        Mark Ng added a comment -

        Created an attachment (id=15239)
        adds simple attribute matching

        I changed the following classes in the commons-digestor 1.6 so it can match
        based on the attribute value

        Modified
        RuleBase.add()
        Digestor.startElement()

        Added
        Rule.attributeXpath
        Rule.getAttributeXpath()
        Rule.setAttributeXpath()
        Digestor.filterRulesByValidAttributeMatch()
        Digestor.useAttributeRule()
        Digestor.rebuildNode()

        For the following exmple.

        <people>
        <person>
        <location type="home">
        <postcode>3190<postcode>
        </id>
        </person>
        </people>

        <digester-rules>
        <pattern value="people/person">
        <object-create-rule classname="com.Person" />
        <pattern value="location[@type='home']">
        <call-method-rule pattern="postcode"
        methodname="setPostcode" paramcount="0"/>
        </pattern>
        <set-next-rule methodname="add" paramtype="java.lang.Object" />

        </pattern>
        </digester-rules>

        The person.postcode value will be 3190 as the xpath e.g.
        people/person/location[@type='home'] /postcode matches the rules.

        If the sample input was as follows then the person.postcode value would not be
        set.

        <people>
        <person>
        <location type="work">
        <postcode>3190<postcode>
        </id>
        </person>
        </people>

        The modification to code is limited to defining one [@XXX] per xpath. Also i do
        not pop all the of the attributes off the stack, only the ones i need. Is there
        a better way to do this?

        Show
        Mark Ng added a comment - Created an attachment (id=15239) adds simple attribute matching I changed the following classes in the commons-digestor 1.6 so it can match based on the attribute value Modified RuleBase.add() Digestor.startElement() Added Rule.attributeXpath Rule.getAttributeXpath() Rule.setAttributeXpath() Digestor.filterRulesByValidAttributeMatch() Digestor.useAttributeRule() Digestor.rebuildNode() For the following exmple. <people> <person> <location type="home"> <postcode>3190<postcode> </id> </person> </people> <digester-rules> <pattern value="people/person"> <object-create-rule classname="com.Person" /> <pattern value="location [@type='home'] "> <call-method-rule pattern="postcode" methodname="setPostcode" paramcount="0"/> </pattern> <set-next-rule methodname="add" paramtype="java.lang.Object" /> </pattern> </digester-rules> The person.postcode value will be 3190 as the xpath e.g. people/person/location [@type='home'] /postcode matches the rules. If the sample input was as follows then the person.postcode value would not be set. <people> <person> <location type="work"> <postcode>3190<postcode> </id> </person> </people> The modification to code is limited to defining one [@XXX] per xpath. Also i do not pop all the of the attributes off the stack, only the ones i need. Is there a better way to do this?
        Hide
        Mark Ng added a comment -

        Created an attachment (id=15240)
        adds simple attribute matching

        I changed the following classes in the commons-digestor 1.6 to allow for simple
        attribute matching.

        Modified
        RuleBase.add()
        Digestor.startElement()

        Added
        Rule.attributeXpath
        Rule.getAttributeXpath()
        Rule.setAttributeXpath()
        Digestor.filterRulesByValidAttributeMatch()
        Digestor.useAttributeRule()
        Digestor.rebuildNode()

        For the following exmple.

        <people>
        <person>
        <location type="home">
        <postcode>3190<postcode>
        </id>
        </person>
        </people>

        <digester-rules>
        <pattern value="people/person">
        <object-create-rule classname="com.Person" />
        <pattern value="location[@type='home']">
        <call-method-rule pattern="postcode"
        methodname="setPostcode" paramcount="0"/>
        </pattern>
        <set-next-rule methodname="add" paramtype="java.lang.Object" />

        </pattern>
        </digester-rules>

        The person.postcode value will be 3190 as the xpath e.g.
        people/person/location[@type='home'] /postcode matches the rules.

        If the sample input was then person.postcode value would not be set.

        <people>
        <person>
        <location type="work">
        <postcode>3190<postcode>
        </id>
        </person>
        </people>

        The modification to code is limited to defining 1 [@XXX] per xpath. This can
        easily be changed. Also i do not pop all the of the attributes off the stack,
        only the ones i need. Is there a better way to do this?

        Show
        Mark Ng added a comment - Created an attachment (id=15240) adds simple attribute matching I changed the following classes in the commons-digestor 1.6 to allow for simple attribute matching. Modified RuleBase.add() Digestor.startElement() Added Rule.attributeXpath Rule.getAttributeXpath() Rule.setAttributeXpath() Digestor.filterRulesByValidAttributeMatch() Digestor.useAttributeRule() Digestor.rebuildNode() For the following exmple. <people> <person> <location type="home"> <postcode>3190<postcode> </id> </person> </people> <digester-rules> <pattern value="people/person"> <object-create-rule classname="com.Person" /> <pattern value="location [@type='home'] "> <call-method-rule pattern="postcode" methodname="setPostcode" paramcount="0"/> </pattern> <set-next-rule methodname="add" paramtype="java.lang.Object" /> </pattern> </digester-rules> The person.postcode value will be 3190 as the xpath e.g. people/person/location [@type='home'] /postcode matches the rules. If the sample input was then person.postcode value would not be set. <people> <person> <location type="work"> <postcode>3190<postcode> </id> </person> </people> The modification to code is limited to defining 1 [@XXX] per xpath. This can easily be changed. Also i do not pop all the of the attributes off the stack, only the ones i need. Is there a better way to do this?
        Hide
        Mark Ng added a comment -

        Created an attachment (id=15241)
        trying to add attachment again for previous post

        Show
        Mark Ng added a comment - Created an attachment (id=15241) trying to add attachment again for previous post
        Hide
        Mark Ng added a comment -

        (From update of attachment 15239)
        THis is a proposed patch.

        Show
        Mark Ng added a comment - (From update of attachment 15239) THis is a proposed patch.
        Hide
        Simon Kitching added a comment -

        Hi Mark,

        I think you attached your patch to the wrong bugzilla entry. Isn't your patch
        addressing this instead?
        http://issues.apache.org/bugzilla/show_bug.cgi?id=31329

        This COM-2057 is not about enhancing the ability of the path matching stuff,
        just about dealing with setting a bean property where the name of the property
        is specified via an attribute and the value via body text.

        Please also provide patches in the format generated by "svn diff" or "diff -u",
        not as complete replacement files. I don't know Digester well enough to be able
        to look at a Digester.java file and see what someone has changed!

        Show
        Simon Kitching added a comment - Hi Mark, I think you attached your patch to the wrong bugzilla entry. Isn't your patch addressing this instead? http://issues.apache.org/bugzilla/show_bug.cgi?id=31329 This COM-2057 is not about enhancing the ability of the path matching stuff, just about dealing with setting a bean property where the name of the property is specified via an attribute and the value via body text. Please also provide patches in the format generated by "svn diff" or "diff -u", not as complete replacement files. I don't know Digester well enough to be able to look at a Digester.java file and see what someone has changed!
        Hide
        Volker Karlmeier added a comment -

        Hi all,

        using xml rules, I managed this by changing the order of the xml-tags:

        Example:
        config.xml:
        <address type="cc">volker@magiccode.eu</address>

        rules.xml:
        <pattern value="address">
        <object-create-rule classname="my.package.MailAddress" />
        <!-- Attention ! bean-property-setter-rule and set-next-rule are called
        in reverse order !!
        -->
        <set-properties-rule />
        <set-next-rule methodname="addMailAddress" paramtype="my.package.MailAddress" />
        <bean-property-setter-rule propertyname="address" />
        </pattern>

        Hope that might help in any way.....

        Regards

        Volker

        Show
        Volker Karlmeier added a comment - Hi all, using xml rules, I managed this by changing the order of the xml-tags: Example: config.xml: <address type="cc">volker@magiccode.eu</address> rules.xml: <pattern value="address"> <object-create-rule classname="my.package.MailAddress" /> <!-- Attention ! bean-property-setter-rule and set-next-rule are called in reverse order !! --> <set-properties-rule /> <set-next-rule methodname="addMailAddress" paramtype="my.package.MailAddress" /> <bean-property-setter-rule propertyname="address" /> </pattern> Hope that might help in any way..... Regards Volker
        Hide
        Simone Tripodi added a comment -

        Fixed on Digester3 /trunk, see r1140140

        There isn't the need of modifying the Digester, the Rules and so on, just a little improvement on BeanPropertySetterRule does the magic.

        Thanks for sharing the idea!

        Show
        Simone Tripodi added a comment - Fixed on Digester3 /trunk, see r1140140 There isn't the need of modifying the Digester , the Rules and so on, just a little improvement on BeanPropertySetterRule does the magic. Thanks for sharing the idea!
        Hide
        Simone Tripodi added a comment -

        included in Apache Commons Digester 3.0 release

        Show
        Simone Tripodi added a comment - included in Apache Commons Digester 3.0 release

          People

          • Assignee:
            Simone Tripodi
            Reporter:
            Simon Kitching
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development