示例#1
0
/**
 * xsltAddAttrElemList:
 * @list:  an XSLT AttrElem list
 * @attr:  the new xsl:attribute node
 *
 * Add the new attribute to the list.
 *
 * Returns the new list pointer
 */
static xsltAttrElemPtr
xsltAddAttrElemList(xsltAttrElemPtr list, xmlNodePtr attr) {
    xsltAttrElemPtr next, cur;

    if (attr == NULL)
	return(list);
    if (list == NULL)
	return(xsltNewAttrElem(attr));
    cur = list;
    while (cur != NULL) {
	next = cur->next;
	if (next == NULL) {
	    cur->next = xsltNewAttrElem(attr);
	    return(list);
	}
	cur = next;
    }
    return(list);
}
示例#2
0
/**
 * xsltMergeAttrSets:
 * @set:  an attribute set
 * @other:  another attribute set
 *
 * Add all the attributes from @other to @set,
 * but drop redefinition of existing values.
 */
static void
xsltMergeAttrSets(xsltAttrSetPtr set, xsltAttrSetPtr other) {
    xsltAttrElemPtr cur;
    xsltAttrElemPtr old = other->attrs;
    int add;

    while (old != NULL) {
	/*
	 * Check that the attribute is not yet in the list
	 */
	cur = set->attrs;
	add = 1;
	while (cur != NULL) {
            xsltStylePreCompPtr curComp = cur->attr->psvi;
            xsltStylePreCompPtr oldComp = old->attr->psvi;

            if ((curComp->name == oldComp->name) &&
                (curComp->ns == oldComp->ns)) {
                add = 0;
                break;
            }
	    if (cur->next == NULL)
		break;
            cur = cur->next;
	}

	if (add == 1) {
	    if (cur == NULL) {
		set->attrs = xsltNewAttrElem(old->attr);
	    } else if (add) {
		cur->next = xsltNewAttrElem(old->attr);
	    }
	}

	old = old->next;
    }
}
示例#3
0
void
xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) {
    const xmlChar *ncname;
    const xmlChar *prefix;
    xmlChar *value;
    xmlNodePtr child;
    xsltAttrElemPtr attrItems;

    if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE))
        return;

    value = xmlGetNsProp(cur, (const xmlChar *)"name", NULL);
    if ((value == NULL) || (*value == 0)) {
        xsltGenericError(xsltGenericErrorContext,
                         "xsl:attribute-set : name is missing\n");
        if (value)
            xmlFree(value);
        return;
    }

    ncname = xsltSplitQName(style->dict, value, &prefix);
    xmlFree(value);
    value = NULL;

    if (style->attributeSets == NULL) {
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
        xsltGenericDebug(xsltGenericDebugContext,
                         "creating attribute set table\n");
#endif
        style->attributeSets = xmlHashCreate(10);
    }
    if (style->attributeSets == NULL)
        return;

    attrItems = xmlHashLookup2(style->attributeSets, ncname, prefix);

    /*
    * Parse the content. Only xsl:attribute elements are allowed.
    */
    child = cur->children;
    while (child != NULL) {
        /*
        * Report invalid nodes.
        */
        if ((child->type != XML_ELEMENT_NODE) ||
                (child->ns == NULL) ||
                (! IS_XSLT_ELEM(child)))
        {
            if (child->type == XML_ELEMENT_NODE)
                xsltTransformError(NULL, style, child,
                                   "xsl:attribute-set : unexpected child %s\n",
                                   child->name);
            else
                xsltTransformError(NULL, style, child,
                                   "xsl:attribute-set : child of unexpected type\n");
        } else if (!IS_XSLT_NAME(child, "attribute")) {
            xsltTransformError(NULL, style, child,
                               "xsl:attribute-set : unexpected child xsl:%s\n",
                               child->name);
        } else {
#ifdef XSLT_REFACTORED
            xsltAttrElemPtr nextAttr, curAttr;

            /*
            * Process xsl:attribute
            * ---------------------
            */

#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
            xsltGenericDebug(xsltGenericDebugContext,
                             "add attribute to list %s\n", ncname);
#endif
            /*
            * The following was taken over from
            * xsltAddAttrElemList().
            */
            if (attrItems == NULL) {
                attrItems = xsltNewAttrElem(child);
            } else {
                curAttr = attrItems;
                while (curAttr != NULL) {
                    nextAttr = curAttr->next;
                    if (curAttr->attr == child) {
                        /*
                        * URGENT TODO: Can somebody explain
                        *  why attrItems is set to curAttr
                        *  here? Is this somehow related to
                        *  avoidance of recursions?
                        */
                        attrItems = curAttr;
                        goto next_child;
                    }
                    if (curAttr->next == NULL)
                        curAttr->next = xsltNewAttrElem(child);
                    curAttr = nextAttr;
                }
            }
            /*
            * Parse the xsl:attribute and its content.
            */
            xsltParseAnyXSLTElem(XSLT_CCTXT(style), child);
#else
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
            xsltGenericDebug(xsltGenericDebugContext,
                             "add attribute to list %s\n", ncname);
#endif
            /*
            * OLD behaviour:
            */
            attrItems = xsltAddAttrElemList(attrItems, child);
#endif
        }

#ifdef XSLT_REFACTORED
next_child:
#endif
        child = child->next;
    }

    /*
    * Process attribue "use-attribute-sets".
    */
    /* TODO check recursion */
    value = xmlGetNsProp(cur, (const xmlChar *)"use-attribute-sets",
                         NULL);
    if (value != NULL) {
        const xmlChar *curval, *endval;
        curval = value;
        while (*curval != 0) {
            while (IS_BLANK(*curval)) curval++;
            if (*curval == 0)
                break;
            endval = curval;
            while ((*endval != 0) && (!IS_BLANK(*endval))) endval++;
            curval = xmlDictLookup(style->dict, curval, endval - curval);
            if (curval) {
                const xmlChar *ncname2 = NULL;
                const xmlChar *prefix2 = NULL;
                xsltAttrElemPtr refAttrItems;

#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
                xsltGenericDebug(xsltGenericDebugContext,
                                 "xsl:attribute-set : %s adds use %s\n", ncname, curval);
#endif
                ncname2 = xsltSplitQName(style->dict, curval, &prefix2);
                refAttrItems = xsltNewAttrElem(NULL);
                if (refAttrItems != NULL) {
                    refAttrItems->set = ncname2;
                    refAttrItems->ns = prefix2;
                    attrItems = xsltMergeAttrElemList(style,
                                                      attrItems, refAttrItems);
                    xsltFreeAttrElem(refAttrItems);
                }
            }
            curval = endval;
        }
        xmlFree(value);
        value = NULL;
    }

    /*
     * Update the value
     */
    /*
    * TODO: Why is this dummy entry needed.?
    */
    if (attrItems == NULL)
        attrItems = xsltNewAttrElem(NULL);
    xmlHashUpdateEntry2(style->attributeSets, ncname, prefix, attrItems, NULL);
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
    xsltGenericDebug(xsltGenericDebugContext,
                     "updated attribute list %s\n", ncname);
#endif
}
示例#4
0
/**
 * xsltMergeAttrElemList:
 * @list:  an XSLT AttrElem list
 * @old:  another XSLT AttrElem list
 *
 * Add all the attributes from list @old to list @list,
 * but drop redefinition of existing values.
 *
 * Returns the new list pointer
 */
static xsltAttrElemPtr
xsltMergeAttrElemList(xsltStylesheetPtr style,
                      xsltAttrElemPtr list, xsltAttrElemPtr old) {
    xsltAttrElemPtr cur;
    int add;

    while (old != NULL) {
        if ((old->attr == NULL) && (old->set == NULL)) {
            old = old->next;
            continue;
        }
        /*
         * Check that the attribute is not yet in the list
         */
        cur = list;
        add = 1;
        while (cur != NULL) {
            if ((cur->attr == NULL) && (cur->set == NULL)) {
                if (cur->next == NULL)
                    break;
                cur = cur->next;
                continue;
            }
            if ((cur->set != NULL) && (cur->set == old->set)) {
                add = 0;
                break;
            }
            if (cur->set != NULL) {
                if (cur->next == NULL)
                    break;
                cur = cur->next;
                continue;
            }
            if (old->set != NULL) {
                if (cur->next == NULL)
                    break;
                cur = cur->next;
                continue;
            }
            if (cur->attr == old->attr) {
                xsltGenericError(xsltGenericErrorContext,
                                 "xsl:attribute-set : use-attribute-sets recursion detected\n");
                return(list);
            }
            if (cur->next == NULL)
                break;
            cur = cur->next;
        }

        if (add == 1) {
            /*
            * Changed to use the string-dict, rather than duplicating
            * @set and @ns; this fixes bug #340400.
            */
            if (cur == NULL) {
                list = xsltNewAttrElem(old->attr);
                if (old->set != NULL) {
                    list->set = xmlDictLookup(style->dict, old->set, -1);
                    if (old->ns != NULL)
                        list->ns = xmlDictLookup(style->dict, old->ns, -1);
                }
            } else if (add) {
                cur->next = xsltNewAttrElem(old->attr);
                if (old->set != NULL) {
                    cur->next->set = xmlDictLookup(style->dict, old->set, -1);
                    if (old->ns != NULL)
                        cur->next->ns = xmlDictLookup(style->dict, old->ns, -1);
                }
            }
        }

        old = old->next;
    }
    return(list);
}