def withAttribute(*args,**attrDict):
if args:<EOL><INDENT>attrs = args[:]<EOL><DEDENT>else:<EOL><INDENT>attrs = attrDict.items()<EOL><DEDENT>attrs = [(k,v) for k,v in attrs]<EOL>def pa(s,l,tokens):<EOL><INDENT>for attrName,attrValue in attrs:<EOL><INDENT>if attrName not in tokens:<EOL><INDENT>raise ParseException(s,l,"<STR_LIT>" + attrName)<EOL><DEDENT>if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue:<EOL><INDENT>raise ParseException(s,l,"<STR_LIT>" %<EOL>(attrName, tokens[attrName], attrValue))<EOL><DEDENT><DEDENT><DEDENT>return pa<EOL>
Helper to create a validating parse action to be used with start tags created
       with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
       with a required attribute value, to avoid false matches on common tags such as
       C{<TD>} or C{<DIV>}.

       Call C{withAttribute} with a series of attribute names and values. Specify the list
       of filter attributes names and values as:
        - keyword arguments, as in C{(align="right")}, or
        - as an explicit dict with C{**} operator, when an attribute name is also a Python
          reserved word, as in C{**{"class":"Customer", "align":"right"}}
        - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
       For attribute names with a namespace prefix, you must use the second form.  Attribute
       names are matched insensitive to upper/lower case.

       To verify that the attribute exists, but without specifying a value, pass
       C{withAttribute.ANY_VALUE} as the value.