Exemple #1
0
/**
 * Returns the attribute with the specified name and namespace URI, or null if
 * this element does not have an attribute with that name in that namespace.
 * @param localName the local name of the attribute.
 * @param namespaceURI the namespace of the attribute.
 * @return the attribute of this element with the specified name and namespace.
 */
Attribute *Element::getAttribute(String localName, String ns) {
	xmlAttr *attr = xmlHasNsProp(NODE(node), localName, ns);
	if(!attr)
		return 0;
	else
		return static_cast<Attribute *>(get(attr));
}
Exemple #2
0
// Inherits XMLSpy generation source function.
xmlNodePtr CNode::InternalGetAt(ENodeType eNodeType, const tstring& sNamespaceURI, const tstring& sName, int nIndex)
{
	xmlChar* szNamespaceURI = NULL;
	if(sNamespaceURI.size() > 0)
		szNamespaceURI = X(sNamespaceURI);

	if (eNodeType == Element)
	{
		int nCount = 0;

		for (xmlNodePtr pNode = m_pDOMNode->children; pNode != NULL; pNode = pNode->next)
			if (pNode->type == XML_ELEMENT_NODE && InternalNamesMatch(pNode, sNamespaceURI, sName))
				if (nCount++ == nIndex)
					return pNode;

		throw CXMLException(1, tstring(_T("Index out of range: ")) + sName);
	}
	else
	{
		xmlAttrPtr pAttr = xmlHasNsProp(m_pDOMNode, X(sName), szNamespaceURI);
		if (pAttr != NULL && pAttr->type != XML_ATTRIBUTE_DECL)
			return (xmlNodePtr)pAttr;
		else
			throw CXMLException(1, tstring(_T("Index out of range: ")) + sName);
	}
}
Exemple #3
0
static xmlNode*
get_xmlNode(LassoNode *node, gboolean lasso_dump)
{
    xmlNode *xmlnode, *t;

    xmlnode = parent_class->get_xmlNode(node, lasso_dump);

    if (LASSO_SAMLP_RESPONSE(node)->Status &&
            has_lib_status(LASSO_SAMLP_RESPONSE(node)->Status->StatusCode)) {
        /* liberty QName, add liberty namespace */
        xmlNewNs(xmlnode, (xmlChar*)LASSO_LIB_HREF, (xmlChar*)LASSO_LIB_PREFIX);
    }


    for (t = xmlnode->children; t && strcmp((char*)t->name, "Assertion"); t = t->next) ;

    if (t && strcmp((char*)t->ns->href, LASSO_LIB_HREF) == 0) {
        /* liberty nodes are not allowed in samlp nodes */
        xmlSetNs(t, xmlNewNs(xmlnode, (xmlChar*)LASSO_SAML_ASSERTION_HREF,
                             (xmlChar*)LASSO_SAML_ASSERTION_PREFIX));
        if (xmlHasNsProp(t, (xmlChar*)"type", (xmlChar*)LASSO_XSI_HREF) == NULL)
            xmlNewNsProp(t, xmlNewNs(xmlnode,
                                     (xmlChar*)LASSO_XSI_HREF,
                                     (xmlChar*)LASSO_XSI_PREFIX),
                         (xmlChar*)"type", (xmlChar*)"lib:AssertionType");
    }

    return xmlnode;
}
Exemple #4
0
static void
insure_namespace(xmlNode *xmlnode, xmlNs *ns)
{
	/* insure children are kept in saml namespace */
	xmlNode *t;
	xmlNs *xsi_ns;

	t = xmlnode->children;
	while (t) {
		if (t->type != XML_ELEMENT_NODE) {
			t = t->next;
			continue;
		}

		if (xmlnode->ns && strcmp((char*)xmlnode->ns->href, LASSO_LIB_HREF) == 0) {
			char *typename, *gtypename;
			GType gtype;

			typename = g_strdup_printf("lib:%sType", xmlnode->name);
			gtypename = g_strdup_printf("LassoSaml%s", xmlnode->name);
			gtype = g_type_from_name(gtypename);

			if (gtype) {
				xmlSetNs(xmlnode, ns);
				if (xmlHasNsProp(t, (xmlChar*)"type",
							(xmlChar*)LASSO_XSI_HREF) == NULL) {
					xsi_ns = xmlNewNs(xmlnode, (xmlChar*)LASSO_XSI_HREF,
							(xmlChar*)LASSO_XSI_PREFIX);
					xmlNewNsProp(xmlnode, xsi_ns, (xmlChar*)"type",
							(xmlChar*)typename);
				}
			}
			lasso_release(gtypename);
			lasso_release(typename);
		}
Exemple #5
0
// boolean hasAttributeNS(n DOMString namespaceURI, in DOMString localName) raises(DOMException);
static void _hasAttributeNS(Request& r, MethodParams& params) {
	const xmlChar* namespaceURI=as_xmlnsuri(r, params, 0);
	const xmlChar* localName=as_xmlname(r, params, 1);

	VXnode& vnode=GET_SELF(r, VXnode);
	xmlNode& element=get_self_element(vnode);

	// write out result
	r.write_no_lang(VBool::get(xmlHasNsProp(&element, localName, namespaceURI)!=0));
}
Exemple #6
0
static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
    IXMLDOMNamedNodeMap *iface,
    BSTR baseName,
    BSTR namespaceURI,
    IXMLDOMNode** qualifiedItem)
{
    xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
    xmlAttrPtr attr;
    xmlChar *name;
    xmlChar *href;

    TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), qualifiedItem);

    if (!baseName) return E_INVALIDARG;

    if (namespaceURI && *namespaceURI)
    {
        href = xmlchar_from_wchar(namespaceURI);
        if (!href) return E_OUTOFMEMORY;
    }
    else
        href = NULL;

    name = xmlchar_from_wchar(baseName);
    if (!name)
    {
        heap_free(href);
        return E_OUTOFMEMORY;
    }

    attr = xmlHasNsProp( This->node, name, href );

    heap_free(name);
    heap_free(href);

    if ( !attr )
    {
        if (qualifiedItem) *qualifiedItem = NULL;
        return S_FALSE;
    }

    if ( qualifiedItem )
    {
        xmlUnlinkNode( (xmlNodePtr) attr );
        xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr );
        *qualifiedItem = create_node( (xmlNodePtr) attr );
    }
    else
    {
        if (xmlRemoveProp(attr) == -1)
            ERR("xmlRemoveProp failed\n");
    }

    return S_OK;
}
Exemple #7
0
static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) /* {{{ */
{
    int len;
    const xmlChar *nqname;

	nqname = xmlSplitQName3(name, &len);
	if (nqname != NULL) {
		xmlNsPtr ns;
		xmlChar *prefix = xmlStrndup(name, len);
		if (prefix && xmlStrEqual(prefix, (xmlChar *)"xmlns")) {
			ns = elem->nsDef;
			while (ns) {
				if (xmlStrEqual(ns->prefix, nqname)) {
					break;
				}
				ns = ns->next;
			}
			xmlFree(prefix);
			return (xmlNodePtr)ns;
		}
		ns = xmlSearchNs(elem->doc, elem, prefix);
		if (prefix != NULL) {
			xmlFree(prefix);
		}
		if (ns != NULL) {
			return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href);
		}
	} else {
		if (xmlStrEqual(name, (xmlChar *)"xmlns")) {
			xmlNsPtr nsPtr = elem->nsDef;
			while (nsPtr) {
				if (nsPtr->prefix == NULL) {
					return (xmlNodePtr)nsPtr;
				}
				nsPtr = nsPtr->next;
			}
			return NULL;
		}
	}
	return (xmlNodePtr)xmlHasNsProp(elem, name, NULL);
}
Exemple #8
0
Attr *
element__attr( Element *el, unsigned char *attr_name, unsigned char *namespace_uri )
{
    xmlAttr *attr;

    if ( namespace_uri )
        attr = xmlHasNsProp( ( xmlNode* ) el, attr_name, namespace_uri ) ;
    else
        attr = xmlHasProp( ( xmlNode* ) el, attr_name ) ;

    return ( Attr* ) attr ;
}
Exemple #9
0
/**
 * This parses an Atom content construct.
 *
 * @param cur	the XML node to be parsed
 * @param ctxt 	a valid feed parser context
 * @returns g_strduped string which must be freed by the caller.
 */
static gchar *
atom10_parse_content_construct (xmlNodePtr cur, feedParserCtxtPtr ctxt)
{
	gchar *ret = NULL;
	
	if (xmlHasNsProp (cur, BAD_CAST"src", NULL )) {
		/*
		   RFC 4287 says a feed must have a summary when there's
		   a src attribute in the content (and the content therefore
		   empty). We are already parsing the summary separately.

		   RFC 4287 also says an entry must contain one link element
		   with rel="alternate", so there's no point in parsing
		   src and setting it as link.
		*/
		ret = NULL;
	} else {
		gchar *type;

		/* determine encoding mode */
		type = xml_get_ns_attribute (cur, "type", NULL);
		
		/* Contents need to be de-encoded and should not contain sub-tags.*/
		if (type && (g_str_equal (type,"html") || !g_ascii_strcasecmp (type, "text/html"))) {
			ret = xhtml_extract (cur, 0, NULL);
		} else if (!type || !strcmp (type, "text") || !strncasecmp (type, "text/",5)) {
			gchar *tmp;
			/* Assume that "text/ *" files can be directly displayed.. kinda stated in the RFC */
			ret = (gchar *)xmlNodeListGetString (cur->doc, cur->xmlChildrenNode, 1);
			
			g_strchug (g_strchomp (ret));
			
			if (!type || !strcasecmp (type, "text"))
				tmp = atom10_mark_up_text_content (ret);
			else
				tmp = g_markup_printf_escaped ("<pre>%s</pre>", ret);
			g_free (ret);
			ret = tmp;
		} else if (!strcmp(type,"xhtml") || !g_ascii_strcasecmp (type, "application/xhtml+xml")) {
			/* The spec says to only show the contents of the div tag that MUST be present */
			ret = xhtml_extract (cur, 2, NULL);
		} else {
			/* Do nothing on unsupported content types. This allows summaries to be used. */
			ret = NULL;
		}
		
		g_free (type);
	}
	
	return ret;
}
Exemple #10
0
// Inherits XMLSpy generation source function.
bool CNode::InternalHasChild(ENodeType eNodeType, const tstring& sNamespaceURI, const tstring& sName)
{
	xmlChar* szNamespaceURI = NULL;
	if(sNamespaceURI.size() > 0)
		szNamespaceURI = X(sNamespaceURI);

	if (eNodeType == Element)
	{
		for (xmlNodePtr pNode = m_pDOMNode->children; pNode != NULL; pNode = pNode->next)
			if (pNode->type == XML_ELEMENT_NODE && InternalNamesMatch(pNode, sNamespaceURI, sName))
				return true;
		
		return false;
	}
	else
		return xmlHasNsProp(m_pDOMNode, X(sName), szNamespaceURI) ? true : false;
}
Exemple #11
0
static HRESULT WINAPI xmlnodemap_getQualifiedItem(
    IXMLDOMNamedNodeMap *iface,
    BSTR baseName,
    BSTR namespaceURI,
    IXMLDOMNode** qualifiedItem)
{
    xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
    xmlAttrPtr attr;
    xmlChar *href;
    xmlChar *name;

    TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), qualifiedItem);

    if (!baseName || !qualifiedItem) return E_INVALIDARG;

    if (namespaceURI && *namespaceURI)
    {
        href = xmlchar_from_wchar(namespaceURI);
        if (!href) return E_OUTOFMEMORY;
    }
    else
        href = NULL;

    name = xmlchar_from_wchar(baseName);
    if (!name)
    {
        heap_free(href);
        return E_OUTOFMEMORY;
    }

    attr = xmlHasNsProp(This->node, name, href);

    heap_free(name);
    heap_free(href);

    if (!attr)
    {
        *qualifiedItem = NULL;
        return S_FALSE;
    }

    *qualifiedItem = create_node((xmlNodePtr)attr);

    return S_OK;
}
Exemple #12
0
// Inherits XMLSpy generation source function.
int CNode::ChildCountInternal(ENodeType eNodeType, const tstring& sNamespaceURI, const tstring& sName)
{
	xmlChar* szNamespaceURI = NULL;
	if(sNamespaceURI.size() > 0)
		szNamespaceURI = X(sNamespaceURI);

	if (eNodeType == Element)
	{
		int nCount = 0;

		for (xmlNodePtr pNode = m_pDOMNode->children; pNode != NULL; pNode = pNode->next)
			if (pNode->type == XML_ELEMENT_NODE && InternalNamesMatch(pNode, sNamespaceURI, sName))
				nCount++;

		return nCount;
	}
	else
		return xmlHasNsProp(m_pDOMNode, X(sName), szNamespaceURI) ? 1 : 0;
}
Exemple #13
0
/**
 * xsltAttributeInternal:
 * @ctxt:  a XSLT process context
 * @node:  the current node in the source tree
 * @inst:  the xsl:attribute element
 * @comp:  precomputed information
 * @fromAttributeSet:  the attribute comes from an attribute-set
 *
 * Process the xslt attribute node on the source node
 */
static void
xsltAttributeInternal(xsltTransformContextPtr ctxt,
                      xmlNodePtr contextNode,
                      xmlNodePtr inst,
                      xsltStylePreCompPtr castedComp,
                      int fromAttributeSet)
{
#ifdef XSLT_REFACTORED
    xsltStyleItemAttributePtr comp =
        (xsltStyleItemAttributePtr) castedComp;
#else
    xsltStylePreCompPtr comp = castedComp;
#endif
    xmlNodePtr targetElem;
    xmlChar *prop = NULL;
    const xmlChar *name = NULL, *prefix = NULL, *nsName = NULL;
    xmlChar *value = NULL;
    xmlNsPtr ns = NULL;
    xmlAttrPtr attr;

    if ((ctxt == NULL) || (contextNode == NULL) || (inst == NULL) ||
            (inst->type != XML_ELEMENT_NODE) )
        return;

    /*
    * A comp->has_name == 0 indicates that we need to skip this instruction,
    * since it was evaluated to be invalid already during compilation.
    */
    if (!comp->has_name)
        return;
    /*
    * BIG NOTE: This previously used xsltGetSpecialNamespace() and
    *  xsltGetNamespace(), but since both are not appropriate, we
    *  will process namespace lookup here to avoid adding yet another
    *  ns-lookup function to namespaces.c.
    */
    /*
    * SPEC XSLT 1.0: Error cases:
    * - Creating nodes other than text nodes during the instantiation of
    *   the content of the xsl:attribute element; implementations may
    *   either signal the error or ignore the offending nodes."
    */

    if (comp == NULL) {
        xsltTransformError(ctxt, NULL, inst,
                           "Internal error in xsltAttributeInternal(): "
                           "The XSLT 'attribute' instruction was not compiled.\n");
        return;
    }
    /*
    * TODO: Shouldn't ctxt->insert == NULL be treated as an internal error?
    *   So report an internal error?
    */
    if (ctxt->insert == NULL)
        return;
    /*
    * SPEC XSLT 1.0:
    *  "Adding an attribute to a node that is not an element;
    *  implementations may either signal the error or ignore the attribute."
    *
    * TODO: I think we should signal such errors in the future, and maybe
    *  provide an option to ignore such errors.
    */
    targetElem = ctxt->insert;
    if (targetElem->type != XML_ELEMENT_NODE)
        return;

    /*
    * SPEC XSLT 1.0:
    * "Adding an attribute to an element after children have been added
    *  to it; implementations may either signal the error or ignore the
    *  attribute."
    *
    * TODO: We should decide whether not to report such errors or
    *  to ignore them; note that we *ignore* if the parent is not an
    *  element, but here we report an error.
    */
    if (targetElem->children != NULL) {
        /*
        * NOTE: Ah! This seems to be intended to support streamed
        *  result generation!.
        */
        xsltTransformError(ctxt, NULL, inst,
                           "xsl:attribute: Cannot add attributes to an "
                           "element if children have been already added "
                           "to the element.\n");
        return;
    }

    /*
    * Process the name
    * ----------------
    */

#ifdef WITH_DEBUGGER
    if (ctxt->debugStatus != XSLT_DEBUG_NONE)
        xslHandleDebugger(inst, contextNode, NULL, ctxt);
#endif

    if (comp->name == NULL) {
        /* TODO: fix attr acquisition wrt to the XSLT namespace */
        prop = xsltEvalAttrValueTemplate(ctxt, inst,
                                         (const xmlChar *) "name", XSLT_NAMESPACE);
        if (prop == NULL) {
            xsltTransformError(ctxt, NULL, inst,
                               "xsl:attribute: The attribute 'name' is missing.\n");
            goto error;
        }
        if (xmlValidateQName(prop, 0)) {
            xsltTransformError(ctxt, NULL, inst,
                               "xsl:attribute: The effective name '%s' is not a "
                               "valid QName.\n", prop);
            /* we fall through to catch any further errors, if possible */
        }

        /*
        * Reject a name of "xmlns".
        */
        if (xmlStrEqual(prop, BAD_CAST "xmlns")) {
            xsltTransformError(ctxt, NULL, inst,
                               "xsl:attribute: The effective name 'xmlns' is not allowed.\n");
            xmlFree(prop);
            goto error;
        }

        name = xsltSplitQName(ctxt->dict, prop, &prefix);
        xmlFree(prop);
    } else {
        /*
        * The "name" value was static.
        */
#ifdef XSLT_REFACTORED
        prefix = comp->nsPrefix;
        name = comp->name;
#else
        name = xsltSplitQName(ctxt->dict, comp->name, &prefix);
#endif
    }

    /*
    * Process namespace semantics
    * ---------------------------
    *
    * Evaluate the namespace name.
    */
    if (comp->has_ns) {
        /*
        * The "namespace" attribute was existent.
        */
        if (comp->ns != NULL) {
            /*
            * No AVT; just plain text for the namespace name.
            */
            if (comp->ns[0] != 0)
                nsName = comp->ns;
        } else {
            xmlChar *tmpNsName;
            /*
            * Eval the AVT.
            */
            /* TODO: check attr acquisition wrt to the XSLT namespace */
            tmpNsName = xsltEvalAttrValueTemplate(ctxt, inst,
                                                  (const xmlChar *) "namespace", XSLT_NAMESPACE);
            /*
            * This fixes bug #302020: The AVT might also evaluate to the
            * empty string; this means that the empty string also indicates
            * "no namespace".
            * SPEC XSLT 1.0:
            *  "If the string is empty, then the expanded-name of the
            *  attribute has a null namespace URI."
            */
            if ((tmpNsName != NULL) && (tmpNsName[0] != 0))
                nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1);
            xmlFree(tmpNsName);
        }

        if (xmlStrEqual(nsName, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
            xsltTransformError(ctxt, NULL, inst,
                               "xsl:attribute: Namespace http://www.w3.org/2000/xmlns/ "
                               "forbidden.\n");
            goto error;
        }
        if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
            prefix = BAD_CAST "xml";
        } else if (xmlStrEqual(prefix, BAD_CAST "xml")) {
            prefix = NULL;
        }
    } else if (prefix != NULL) {
        /*
        * SPEC XSLT 1.0:
        *  "If the namespace attribute is not present, then the QName is
        *  expanded into an expanded-name using the namespace declarations
        *  in effect for the xsl:attribute element, *not* including any
        *  default namespace declaration."
        */
        ns = xmlSearchNs(inst->doc, inst, prefix);
        if (ns == NULL) {
            /*
            * Note that this is treated as an error now (checked with
            *  Saxon, Xalan-J and MSXML).
            */
            xsltTransformError(ctxt, NULL, inst,
                               "xsl:attribute: The QName '%s:%s' has no "
                               "namespace binding in scope in the stylesheet; "
                               "this is an error, since the namespace was not "
                               "specified by the instruction itself.\n", prefix, name);
        } else
            nsName = ns->href;
    }

    if (fromAttributeSet) {
        /*
        * This tries to ensure that xsl:attribute(s) coming
        * from an xsl:attribute-set won't override attribute of
        * literal result elements or of explicit xsl:attribute(s).
        * URGENT TODO: This might be buggy, since it will miss to
        *  overwrite two equal attributes both from attribute sets.
        */
        attr = xmlHasNsProp(targetElem, name, nsName);
        if (attr != NULL)
            return;
    }

    /*
    * Find/create a matching ns-decl in the result tree.
    */
    ns = NULL;

#if 0
    if (0) {
        /*
        * OPTIMIZE TODO: How do we know if we are adding to a
        *  fragment or to the result tree?
        *
        * If we are adding to a result tree fragment (i.e., not to the
        * actual result tree), we'll don't bother searching for the
        * ns-decl, but just store it in the dummy-doc of the result
        * tree fragment.
        */
        if (nsName != NULL) {
            /*
            * TODO: Get the doc of @targetElem.
            */
            ns = xsltTreeAcquireStoredNs(some doc, nsName, prefix);
        }
    }
#endif

    if (nsName != NULL) {
        /*
        * Something about ns-prefixes:
        * SPEC XSLT 1.0:
        *  "XSLT processors may make use of the prefix of the QName specified
        *  in the name attribute when selecting the prefix used for outputting
        *  the created attribute as XML; however, they are not required to do
        *  so and, if the prefix is xmlns, they must not do so"
        */
        /*
        * xsl:attribute can produce a scenario where the prefix is NULL,
        * so generate a prefix.
        */
        if ((prefix == NULL) || xmlStrEqual(prefix, BAD_CAST "xmlns")) {
            xmlChar *pref = xmlStrdup(BAD_CAST "ns_1");

            ns = xsltGetSpecialNamespace(ctxt, inst, nsName, pref, targetElem);

            xmlFree(pref);
        } else {
            ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix,
                                         targetElem);
        }
        if (ns == NULL) {
            xsltTransformError(ctxt, NULL, inst,
                               "Namespace fixup error: Failed to acquire an in-scope "
                               "namespace binding for the generated attribute '{%s}%s'.\n",
                               nsName, name);
            goto error;
        }
    }
    /*
    * Construction of the value
    * -------------------------
    */
    if (inst->children == NULL) {
        /*
        * No content.
        * TODO: Do we need to put the empty string in ?
        */
        attr = xmlSetNsProp(ctxt->insert, ns, name, (const xmlChar *) "");
    } else if ((inst->children->next == NULL) &&
               ((inst->children->type == XML_TEXT_NODE) ||
                (inst->children->type == XML_CDATA_SECTION_NODE)))
    {
        xmlNodePtr copyTxt;

        /*
        * xmlSetNsProp() will take care of duplicates.
        */
        attr = xmlSetNsProp(ctxt->insert, ns, name, NULL);
        if (attr == NULL) /* TODO: report error ? */
            goto error;
        /*
        * This was taken over from xsltCopyText() (transform.c).
        */
        if (ctxt->internalized &&
                (ctxt->insert->doc != NULL) &&
                (ctxt->insert->doc->dict == ctxt->dict))
        {
            copyTxt = xmlNewText(NULL);
            if (copyTxt == NULL) /* TODO: report error */
                goto error;
            /*
            * This is a safe scenario where we don't need to lookup
            * the dict.
            */
            copyTxt->content = inst->children->content;
            /*
            * Copy "disable-output-escaping" information.
            * TODO: Does this have any effect for attribute values
            *  anyway?
            */
            if (inst->children->name == xmlStringTextNoenc)
                copyTxt->name = xmlStringTextNoenc;
        } else {
            /*
            * Copy the value.
            */
            copyTxt = xmlNewText(inst->children->content);
            if (copyTxt == NULL) /* TODO: report error */
                goto error;
        }
        attr->children = attr->last = copyTxt;
        copyTxt->parent = (xmlNodePtr) attr;
        copyTxt->doc = attr->doc;
        /*
        * Copy "disable-output-escaping" information.
        * TODO: Does this have any effect for attribute values
        *  anyway?
        */
        if (inst->children->name == xmlStringTextNoenc)
            copyTxt->name = xmlStringTextNoenc;

        /*
         * since we create the attribute without content IDness must be
         * asserted as a second step
         */
        if ((copyTxt->content != NULL) &&
                (xmlIsID(attr->doc, attr->parent, attr)))
            xmlAddID(NULL, attr->doc, copyTxt->content, attr);
    } else {
        /*
        * The sequence constructor might be complex, so instantiate it.
        */
        value = xsltEvalTemplateString(ctxt, contextNode, inst);
        if (value != NULL) {
            attr = xmlSetNsProp(ctxt->insert, ns, name, value);
            xmlFree(value);
        } else {
            /*
            * TODO: Do we have to add the empty string to the attr?
            * TODO: Does a  value of NULL indicate an
            *  error in xsltEvalTemplateString() ?
            */
            attr = xmlSetNsProp(ctxt->insert, ns, name,
                                (const xmlChar *) "");
        }
    }

error:
    return;
}
Exemple #14
0
/* Note: this function is called for both item and feed context */
static gchar *
atom10_parse_link (xmlNodePtr cur, feedParserCtxtPtr ctxt, struct atom10ParserState *state)
{
	gchar *href, *alternate = NULL;
	
	href = xml_get_ns_attribute (cur, "href", NULL);
	if (href) {
		xmlChar *baseURL = xmlNodeGetBase (cur->doc, cur);
		gchar *url, *relation, *type, *escTitle = NULL, *title;
		const gchar *feedURL = subscription_get_homepage (ctxt->subscription);
		
		if (!baseURL && feedURL && feedURL[0] != '|' && strstr (feedURL, "://"))
			baseURL = xmlStrdup (BAD_CAST (feedURL));
		url = (gchar *)common_build_url (href, (gchar *)baseURL);

		type = xml_get_ns_attribute (cur, "type", NULL);
		relation = xml_get_ns_attribute (cur, "rel", NULL);
		title = xml_get_ns_attribute (cur, "title", NULL);
		if (title)
			escTitle = g_markup_escape_text (title, -1);
		
		if (!xmlHasNsProp (cur, BAD_CAST"rel", NULL) || !relation || g_str_equal (relation, BAD_CAST"alternate"))
			alternate = g_strdup (url);
		else if (g_str_equal (relation, "replies")) {
			if (!type || g_str_equal (type, BAD_CAST"application/atom+xml")) {
				gchar *commentUri = (gchar *)common_build_url ((gchar *)url, subscription_get_homepage (ctxt->subscription));
				if (ctxt->item)
					metadata_list_set (&ctxt->item->metadata, "commentFeedUri", commentUri);
				g_free (commentUri);
			}
		} else if (g_str_equal (relation, "enclosure")) {
			if (ctxt->item) {
				gsize length = 0;
				gchar *lengthStr = xml_get_ns_attribute (cur, "length", NULL);
				if (lengthStr)
					length = atol (lengthStr);
				g_free (lengthStr);
				
				gchar *encStr = enclosure_values_to_string (url, type, length, FALSE /* not yet downloaded */);
				ctxt->item->metadata = metadata_list_append (ctxt->item->metadata, "enclosure", encStr);
				ctxt->item->hasEnclosure = TRUE;
				g_free (encStr);
			}
		} else if (g_str_equal (relation, "related") || g_str_equal (relation, "via")) {	
			if (ctxt->item)
				ctxt->item->metadata = metadata_list_append (ctxt->item->metadata, relation, url);
		} else {
			/* g_warning ("Unhandled Atom link with unexpected relation \"%s\"\n", relation); */
		}
		xmlFree (title);
		xmlFree (baseURL);
		g_free (escTitle);
		g_free (url);
		g_free(relation);
		g_free(type);
		g_free(href);
	} else {
		/* FIXME: @href is required, this document is not valid Atom */;
	}
	
	return alternate;
}
/**
 * xsltAttributeInternal:
 * @ctxt:  a XSLT process context
 * @node:  the node in the source tree.
 * @inst:  the xsl:attribute element
 * @comp:  precomputed information
 * @fromAttributeSet:  the attribute comes from an attribute-set
 *
 * Process the xslt attribute node on the source node
 */
static void
xsltAttributeInternal(xsltTransformContextPtr ctxt, xmlNodePtr node,
                      xmlNodePtr inst,
		      xsltStylePreCompPtr castedComp,
                      int fromAttributeSet) {
#ifdef XSLT_REFACTORED
    xsltStyleItemAttributePtr comp =
	(xsltStyleItemAttributePtr) castedComp;
    /*
    * TODO: Change the fields of the compiled struct:
    *  1) @name (char)
    *  2) @nameType (String, AVT)
    *  3) @nsName (char)
    *  4) nsNameType (None, String, AVT)
    */
#else
    xsltStylePreCompPtr comp = castedComp;
#endif
    xmlNodePtr targetElem;
    xmlChar *prop = NULL;    
    const xmlChar *name = NULL, *prefix = NULL, *nsName = NULL;
    xmlChar *value = NULL;
    xmlNsPtr ns = NULL;
    xmlAttrPtr attr;    

    if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
        return;
    /*
    * BIG NOTE: This previously used xsltGetSpecialNamespace() and
    *  xsltGetNamespace(), but since both are not appropriate, we
    *  will process namespace lookup here to avoid adding yet another
    *  ns-lookup function to namespaces.c.
    */
    /*
    * SPEC XSLT 1.0: Error cases:
    * - Creating nodes other than text nodes during the instantiation of
    *   the content of the xsl:attribute element; implementations may
    *   either signal the error or ignore the offending nodes."
    */

    if (comp == NULL) {
        xsltTransformError(ctxt, NULL, inst,
	    "Internal error in xsltAttributeInternal(): "
	    "The instruction was no compiled.\n");
        return;
    }    
    /*
    * TODO: Shouldn't ctxt->insert == NULL be treated as an internal error?
    *   So report an internal error?
    */
    if (ctxt->insert == NULL)
        return;    
    /*
    * SPEC XSLT 1.0:
    *  "Adding an attribute to a node that is not an element;
    *  implementations may either signal the error or ignore the attribute."
    *
    * TODO: I think we should signal such errors in the future, and maybe
    *  provide an option to ignore such errors.
    */
    targetElem = ctxt->insert;
    if (targetElem->type != XML_ELEMENT_NODE)
	return;
    
    /*
    * SPEC XSLT 1.0:
    * "Adding an attribute to an element after children have been added
    *  to it; implementations may either signal the error or ignore the
    *  attribute."
    *
    * TODO: We should decide whether not to report such errors or
    *  to ignore them; note that we *ignore* if the parent is not an
    *  element, but here we report an error.
    */
    if (targetElem->children != NULL) {
	/*
	* NOTE: Ah! This seems to be intended to support streamed
	*  result generation!.
	*/
        xsltTransformError(ctxt, NULL, inst,
	    "xsl:attribute: Cannot add attributes to an "
	    "element if children have been already added "
	    "to the element.\n");
        return;
    }

    /*
    * Process the name
    * ----------------
    */
    if (!comp->has_name) /* TODO: raise error */
        return;

#ifdef WITH_DEBUGGER
    if (ctxt->debugStatus != XSLT_DEBUG_NONE)
        xslHandleDebugger(inst, node, NULL, ctxt);
#endif

    if (comp->name == NULL) {
	/* TODO: fix attr acquisition wrt to the XSLT namespace */
        prop = xsltEvalAttrValueTemplate(ctxt, inst,
	    (const xmlChar *) "name", XSLT_NAMESPACE);
        if (prop == NULL) {
            xsltTransformError(ctxt, NULL, inst,
		"xsl:attribute: The attribute 'name' is missing.\n");
            goto error;
        }
	if (xmlValidateQName(prop, 0)) {
	    xsltTransformError(ctxt, NULL, inst,
		"xsl:attribute: The effective name '%s' is not a "
		"valid QName.\n", prop);
	    /* we fall through to catch any further errors, if possible */
	}
	name = xsltSplitQName(ctxt->dict, prop, &prefix);
	xmlFree(prop);
    } else {
	name = xsltSplitQName(ctxt->dict, comp->name, &prefix);
    }

    if (!xmlStrncasecmp(prefix, (xmlChar *) "xmlns", 5)) {
#ifdef WITH_XSLT_DEBUG_PARSING
        xsltGenericDebug(xsltGenericDebugContext,
	    "xsltAttribute: xmlns prefix forbidden\n");
#endif
	/*
	* SPEC XSLT 1.0:
	*  "It is an error if the string that results from instantiating
	*  the attribute value template is not a QName or is the string
	*  xmlns. An XSLT processor may signal the error; if it does not
	*  signal the error, it must recover by not adding the attribute
	*  to the result tree."
	* TODO: Decide which way to go here.
	*/
        goto error;
    }
    /*
    * Process namespace semantics
    * ---------------------------
    *
    * Evaluate the namespace name.
    */
    if (comp->has_ns) {	 
	if (comp->ns != NULL) {
	    if (comp->ns[0] != 0)
		nsName = comp->ns;
	} else {
	    xmlChar *tmpNsName;
	    /*
	    * Eval the AVT.
	    */
	    /* TODO: check attr acquisition wrt to the XSLT namespace */
	    tmpNsName = xsltEvalAttrValueTemplate(ctxt, inst,
		(const xmlChar *) "namespace", XSLT_NAMESPACE);	
	    /*
	    * This fixes bug #302020: The AVT might also evaluate to the 
	    * empty string; this means that the empty string also indicates
	    * "no namespace".
	    * SPEC XSLT 1.0:
	    *  "If the string is empty, then the expanded-name of the
	    *  attribute has a null namespace URI."
	    */
	    if ((tmpNsName != NULL) && (tmpNsName[0] != 0))
		nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1);
	    xmlFree(tmpNsName);		
	};	    
    } else if (prefix != NULL) {
	/*
	* SPEC XSLT 1.0:
	*  "If the namespace attribute is not present, then the QName is
	*  expanded into an expanded-name using the namespace declarations
	*  in effect for the xsl:attribute element, *not* including any
	*  default namespace declaration."
	*/	
	ns = xmlSearchNs(inst->doc, inst, prefix);
	if (ns == NULL) {
	    /*
	    * Note that this is treated as an error now (checked with
	    *  Saxon, Xalan-J and MSXML).
	    */
	    xsltTransformError(ctxt, NULL, inst,
		"xsl:attribute: The effective prefix '%s', has no "
		"namespace binding in scope in the stylesheet; "
		"this is an error, since the namespace was not "
		"specified by the instruction itself.\n", prefix);
	} else
	    nsName = ns->href;	
    }

    if (fromAttributeSet) {
	/*
	* I think this tries to ensure that xsl:attribute(s) coming
	* from an xsl:attribute-set won't override attribute of
	* literal result elements or of explicit xsl:attribute(s).
	*/
	attr = xmlHasNsProp(targetElem, name, nsName);
	if (attr != NULL)
	    return;
    }

    /*
    * Something about ns-prefixes:
    * SPEC XSLT 1.0:
    *  "XSLT processors may make use of the prefix of the QName specified
    *  in the name attribute when selecting the prefix used for outputting
    *  the created attribute as XML; however, they are not required to do
    *  so and, if the prefix is xmlns, they must not do so"
    */        
    /*
    * Find/create a matching ns-decl in the result tree.
    */
    ns = NULL;
#if 0
    if (0) {	
	/*
	* OPTIMIZE TODO: How do we know if we are adding to a
	*  fragment or not?
	*
	* If we are adding to a result tree fragment (i.e., not to the
	* actual result tree), we'll don't bother searching for the
	* ns-decl, but just store it in the dummy-doc of the result
	* tree fragment.
	*/
	if (nsName != NULL) {
	    ns = xsltTreeAcquireStoredNs(ctxt->document->doc, nsName,
		prefix);
	}
    }
#endif
    if (nsName != NULL) {
	/*
	* The owner-element might be in the same namespace.
	*/
	if ((targetElem->ns != NULL) &&
	    (targetElem->ns->prefix != NULL) &&	    
	    xmlStrEqual(targetElem->ns->href, nsName))
	{
	    ns = targetElem->ns;
	    goto namespace_finished;
	}
	if (prefix != NULL) {
	    /*
	    * Search by ns-prefix.
	    */
	    ns = xmlSearchNs(targetElem->doc, targetElem, prefix);
	    if ((ns != NULL) && (xmlStrEqual(ns->href, nsName))) {
		goto namespace_finished;
	    }
	}
	/*
	* Fallback to a search by ns-name.
	*/	
	ns = xmlSearchNsByHref(targetElem->doc, targetElem, nsName);
	if ((ns != NULL) && (ns->prefix != NULL)) {
	    goto namespace_finished;
	}
	/*
	* OK, we need to declare the namespace on the target element.
	*/
	if (prefix) {
	    if (targetElem->nsDef != NULL) {
		ns = targetElem->nsDef;
		do {
		    if ((ns->prefix) && xmlStrEqual(ns->prefix, prefix)) {
			/*
			* The prefix is aready occupied.
			*/
			break;
		    }
		    ns = ns->next;
		} while (ns != NULL);
		if (ns == NULL) {
		    ns = xmlNewNs(targetElem, nsName, prefix);
		    goto namespace_finished;
		}
	    }
	}
	/*
	* Generate a new prefix.
	*/
	{
	    const xmlChar *basepref = prefix;
	    xmlChar pref[30];
	    int counter = 1;
	    
	    if (prefix != NULL)
		basepref = prefix;
	    else
		basepref = xmlStrdup(BAD_CAST "ns");
	    
	    do {
		snprintf((char *) pref, 30, "%s%d",
		    basepref, counter++);
		ns = xmlSearchNs(targetElem->doc, targetElem, BAD_CAST pref);
		if (counter > 1000) {
		    xsltTransformError(ctxt, NULL, inst,
		    	"Namespace fixup error: Failed to compute a "
			"new unique ns-prefix for the generated attribute "
			"{%s}%s'.\n", nsName, name);		    			
		    ns = NULL;
		    break;
		}
	    } while (ns != NULL);
	    if (basepref != prefix)
		xmlFree((xmlChar *)basepref);
	    ns = xmlNewNs(targetElem, nsName, BAD_CAST pref);
	}

namespace_finished:

	if (ns == NULL) {
	    xsltTransformError(ctxt, NULL, inst,
		"Namespace fixup error: Failed to acquire an in-scope "
		"namespace binding of the generated attribute '{%s}%s'.\n",
		nsName, name);
	    /*
	    * TODO: Should we just stop here?
	    */
	}
    }
    /*
    * Construction of the value
    * -------------------------
    */
    if (inst->children == NULL) {
	/*
	* No content.
	* TODO: Do we need to put the empty string in ?
	*/
	attr = xmlSetNsProp(ctxt->insert, ns, name, (const xmlChar *) "");
    } else if ((inst->children->next == NULL) && 
	    ((inst->children->type == XML_TEXT_NODE) ||
	     (inst->children->type == XML_CDATA_SECTION_NODE)))
    {
	xmlNodePtr origTxt = inst->children, copyTxt;
	/*
	* Optimization: if the content is just 1 text node, then
	* just need to copy it over, or just assign it to the result
	* if the string is shared.
	*/
	attr = xmlSetNsProp(ctxt->insert, ns, name, NULL);
	if (attr == NULL) /* TODO: report error ? */
	    goto error;
	/*
	* This was taken over from xsltCopyText() (transform.c).
	*/
	if (ctxt->internalized &&
	    (ctxt->insert->doc != NULL) &&
	    (ctxt->insert->doc->dict == ctxt->dict))
	{
	    copyTxt = xmlNewText(NULL);
	    if (copyTxt == NULL) /* TODO: report error */
		goto error;
	    /*
	    * This is a safe scenario where we don't need to lookup
	    * the dict.
	    */
	    copyTxt->content = origTxt->content;
	    /*
	    * Copy "disable-output-escaping" information.
	    * TODO: Does this have any effect for attribute values
	    *  anyway?
	    */
	    if (origTxt->name == xmlStringTextNoenc)
		copyTxt->name = xmlStringTextNoenc;
	} else {
	    /*
	    * Copy the value.
	    */
	    copyTxt = xmlNewText(origTxt->content);
	    if (copyTxt == NULL) /* TODO: report error */
		goto error;
	    /*
	    * Copy "disable-output-escaping" information.
	    * TODO: Does this have any effect for attribute values
	    *  anyway?
	    */
	    if (origTxt->name == xmlStringTextNoenc)
		copyTxt->name = xmlStringTextNoenc;
	}
	if (copyTxt != NULL) {
	    copyTxt->doc = attr->doc;
	    xmlAddChild((xmlNodePtr) attr, copyTxt);
	}
    } else {
	/*
	* The sequence constructor might be complex, so instantiate it.
	*/
	value = xsltEvalTemplateString(ctxt, node, inst);
	if (value != NULL) {
	    attr = xmlSetNsProp(ctxt->insert, ns, name, value);
	    xmlFree(value);
	} else {
	    /*
	    * TODO: Do we have to add the empty string to the attr?
	    */
	    attr = xmlSetNsProp(ctxt->insert, ns, name,
		(const xmlChar *) "");
	}
    }

error:
    return;    
}