当前位置: 首页>>代码示例>>Java>>正文


Java XPathAPI.selectSingleNode方法代码示例

本文整理汇总了Java中org.apache.xpath.XPathAPI.selectSingleNode方法的典型用法代码示例。如果您正苦于以下问题:Java XPathAPI.selectSingleNode方法的具体用法?Java XPathAPI.selectSingleNode怎么用?Java XPathAPI.selectSingleNode使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在org.apache.xpath.XPathAPI的用法示例。


在下文中一共展示了XPathAPI.selectSingleNode方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Java代码示例。

示例1: preconfigure

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
@Override
public void preconfigure(Element element) throws Exception {
	super.preconfigure(element);
	
	String version = element.getAttribute("version");
	
	if (version!= null && VersionUtils.compare(version, "7.0.0") < 0) {
		Engine.logDatabaseObjectManager.info("Migration to 7.0.0 for MouseAdvanceStatement, migrate to javascriptable properties.");
		Document doc = element.getOwnerDocument();
		
		for (String propertyName : Arrays.asList("screenX", "screenY", "clientX", "clientY", "ctrlKey", "altKey", "shiftKey", "metKey", "button")) {
			Element exElt = (Element) XPathAPI.selectSingleNode(element, "property[@name='" + propertyName +"']/*");
			Element newElt = doc.createElement("java.lang.String");
			
			newElt.setAttribute("value", exElt.getAttribute("value"));
			exElt.getParentNode().replaceChild(newElt, exElt);
		}
	}
}
 
开发者ID:convertigo,项目名称:convertigo-engine,代码行数:20,代码来源:MouseAdvanceStatement.java

示例2: main

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
public static void main(String[] args) throws Exception {
    Document doc = XmlUtils.loadDoc("/testcode/xpath/data.xml");

    String input = args.length != 0 ? args[1] : "guess' or '1'='1";
    String query = "//groups/group[@id='" + input + "']/writeAccess/text()";

    //selectNodeIterator
    NodeIterator iterator = XPathAPI.selectNodeIterator(doc, query);
    XmlUtils.printNodeIterator(iterator);

    //selectNodeList
    NodeList nodeList = XPathAPI.selectNodeList(doc, query);
    XmlUtils.printNodeList(nodeList);

    //selectSingleNode
    Node node = XPathAPI.selectSingleNode(doc, query);
    XmlUtils.printNode(node);

    //Static string (safe)
    Node node2 = XPathAPI.selectSingleNode(doc, "//groups/group[@id='guess']/writeAccess/text()".toLowerCase());
    XmlUtils.printNode(node2);
}
 
开发者ID:blackarbiter,项目名称:Android_Code_Arbiter,代码行数:23,代码来源:XPathApacheXPathApi.java

示例3: postSign

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
public void postSign(Element signatureElement, List<X509Certificate> signingCertificateChain) {
	Document document = signatureElement.getOwnerDocument();
	Element nsElement = document.createElement("nsElement");
	nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
	nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:xades", XAdESXLSignatureFacet.XADES_NAMESPACE);
	Element qualifyingPropertiesElement;
	try {
		qualifyingPropertiesElement = (Element) XPathAPI.selectSingleNode(signatureElement,
				"ds:Object/xades:QualifyingProperties", nsElement);
	} catch (TransformerException e) {
		throw new RuntimeException("XPath error: " + e.getMessage(), e);
	}
	String namespacePrefix = qualifyingPropertiesElement.getPrefix();
	if (null == namespacePrefix || namespacePrefix.isEmpty()) {
		namespacePrefix = "";
	} else {
		namespacePrefix = namespacePrefix + ":";
	}
	Element unsignedPropertiesElement = document.createElementNS(XAdESXLSignatureFacet.XADES_NAMESPACE,
			namespacePrefix + "UnsignedProperties");
	qualifyingPropertiesElement.appendChild(unsignedPropertiesElement);
	Element unsignedSignaturePropertiesElement = document.createElementNS(XAdESXLSignatureFacet.XADES_NAMESPACE,
			namespacePrefix + "UnsignedSignatureProperties");
	unsignedPropertiesElement.appendChild(unsignedSignaturePropertiesElement);
}
 
开发者ID:e-Contract,项目名称:eid-applet,代码行数:26,代码来源:Office2010SignatureFacet.java

示例4: sign

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
/**
 * Canonizes and signs a given input with the authentication private key.
 * of the EBICS user.
 * 
 * <p>The given input to be signed is first Canonized using the 
 * http://www.w3.org/TR/2001/REC-xml-c14n-20010315 algorithm.
 * 
 * <p>The element to be canonized is only the SignedInfo element that should be
 * contained in the request to be signed. Otherwise, a {@link TransformationException}
 * is thrown.
 * 
 * <p> The namespace of the SignedInfo element should be named <b>ds</b> as specified in
 * the EBICS specification for common namespaces nomination.
 * 
 * <p> The signature is ensured using the user X002 private key. This step is done in
 * {@link EbicsUser#authenticate(byte[]) authenticate}.
 * 
 * @param toSign the input to sign
 * @return the signed input
 * @throws EbicsException signature fails.
 */
public byte[] sign(byte[] toSign) throws EbicsException {
  try {
    DocumentBuilderFactory 		factory;
    DocumentBuilder			builder;
    Document				document;
    Node 				node;
    Canonicalizer 			canonicalizer;

    factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    factory.setValidating(true);
    builder = factory.newDocumentBuilder();
    builder.setErrorHandler(new IgnoreAllErrorHandler());
    document = builder.parse(new ByteArrayInputStream(toSign));
    node = XPathAPI.selectSingleNode(document, "//ds:SignedInfo");
    canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
    return user.authenticate(canonicalizer.canonicalizeSubtree(node));
  } catch(Exception e) {
    throw new EbicsException(e.getMessage());
  }
}
 
开发者ID:pinaraf,项目名称:ebics,代码行数:43,代码来源:SignedInfo.java

示例5: getComplexFormats

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
private void getComplexFormats(Parameter param, Node n) throws JDOMException, KettleException, DOMException, TransformerException{		
	Node complex_default =  XPathAPI.selectSingleNode(n, DEFAULT_FORMAT_EXPR);
	AbstractFormat defaultFormat = null;
	if(complex_default!= null){ 	    	
    	defaultFormat = buildComplexFormat(complex_default);
		param.setDefaultFormat(defaultFormat);
    }

    Node complex_supported;
    NodeIterator nodeIt = XPathAPI.selectNodeIterator(n, SUPPORTED_FORMATS_EXPR);
    while ((complex_supported = nodeIt.nextNode())!= null){ 	    	
    	param.addSupportedFormat(buildComplexFormat(complex_supported));
    }
    
    if(param.getSupportedFormats().isEmpty() && defaultFormat != null)
    	param.addSupportedFormat(defaultFormat);	    	
}
 
开发者ID:icholy,项目名称:geokettle-2.0,代码行数:18,代码来源:ParameterBuilder.java

示例6: parseParameter

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
private Parameter parseParameter(Node n) throws JDOMException, KettleException, TransformerException{
	Parameter param = buildParameter(n);	
	Node complex_node = XPathAPI.selectSingleNode(n, complex_expr);
	if (complex_node != null)
		getComplexFormats(param, complex_node);	
	else{		
		Node bbox_node =  XPathAPI.selectSingleNode(n, bbox_expr);	
		if (bbox_node != null)
			getBoundingBoxFormats(param, bbox_node);	
		else{		
			Node literal_node =  XPathAPI.selectSingleNode(n, literal_expr);	
			if (literal_node != null)
				getLiteralFormats(param, literal_node);							
		}
    }	
	return param;
}
 
开发者ID:icholy,项目名称:geokettle-2.0,代码行数:18,代码来源:ParameterBuilder.java

示例7: sign

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
/**
 * Canonizes and signs a given input with the authentication private key.
 * of the EBICS user.
 * 
 * <p>The given input to be signed is first Canonized using the 
 * http://www.w3.org/TR/2001/REC-xml-c14n-20010315 algorithm.
 * 
 * <p>The element to be canonized is only the SignedInfo element that should be
 * contained in the request to be signed. Otherwise, a {@link TransformationException}
 * is thrown.
 * 
 * <p> The namespace of the SignedInfo element should be named <b>ds</b> as specified in
 * the EBICS specification for common namespaces nomination.
 * 
 * <p> The signature is ensured using the user X002 private key. This step is done in
 * {@link EbicsUser#authenticate(byte[]) authenticate}.
 * 
 * @param toSign the input to sign
 * @return the signed input
 * @throws EbicsException signature fails.
 */
public byte[] sign(byte[] toSign) throws AxelorException {
  try {
    DocumentBuilderFactory 		factory;
    DocumentBuilder			builder;
    Document				document;
    Node 				node;
    Canonicalizer 			canonicalizer;

    factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    factory.setValidating(true);
    builder = factory.newDocumentBuilder();
    builder.setErrorHandler(new IgnoreAllErrorHandler());
    document = builder.parse(new ByteArrayInputStream(toSign));
    node = XPathAPI.selectSingleNode(document, "//ds:SignedInfo");
    canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
    return Beans.get(EbicsUserService.class).authenticate(user, canonicalizer.canonicalizeSubtree(node));
  } catch(Exception e) {
    e.printStackTrace();
    throw new AxelorException(e, IException.CONFIGURATION_ERROR);
  }
}
 
开发者ID:axelor,项目名称:axelor-business-suite,代码行数:44,代码来源:SignedInfo.java

示例8: getLocalIdentifier

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
/**
     * Extract the local identifier from the native item
     *
     * @param nativeItem native Item object
     * @return local identifier
     */
    public String getLocalIdentifier(Object nativeItem) {
//  	logger.debug("getLocalIdentifier: nativeItem=" + nativeItem);
	HashMap hashMap = (HashMap)nativeItem;
	Node dataNode = (Node) hashMap.get("header");
// 	MessageElement messageElement = dataNode.get_any()[0];
//	StringBuffer sb = new StringBuffer();
	try {
// 	    Element recordEl = messageElement.getAsDOM();
	    Element recordEl = (Element)dataNode;
// 	    logger.debug("NodeRecordFactory.getLocalIdentifier: recordEl=" + recordEl);
	    Node identifierNode =
		XPathAPI.selectSingleNode(
					  recordEl,
					  "/oai:header/oai:identifier",
					  xmlnsEl);
// 	    logger.debug("NodeRecordFactory.getLocalIdentifier: identifierNode=" + identifierNode);
	    if (identifierNode != null) {
		return XPathAPI.eval(identifierNode, "string()").str();
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return null;
    }
 
开发者ID:openpreserve,项目名称:oaicat,代码行数:31,代码来源:NodeRecordFactory.java

示例9: getDatestamp

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
/**
     * get the datestamp from the item
     *
     * @param nativeItem a native item presumably containing a datestamp somewhere
     * @return a String containing the datestamp for the item
     * @exception IllegalArgumentException Something is wrong with the argument.
     */
    public String getDatestamp(Object nativeItem)
	throws IllegalArgumentException {
	HashMap hashMap = (HashMap)nativeItem;
	Node dataNode = (Node) hashMap.get("header");
// 	MessageElement messageElement = dataNode.get_any()[0];
	try {
// 	    Element recordEl = messageElement.getAsDOM();
	    Element recordEl = (Element)dataNode;
	    Node datestampNode =
		XPathAPI.selectSingleNode(
					  recordEl,
					  "/oai:header/oai:datestamp",
					  xmlnsEl);
	    if (datestampNode != null) {
		return XPathAPI.eval(datestampNode, "string()").str();
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return null;
    }
 
开发者ID:openpreserve,项目名称:oaicat,代码行数:29,代码来源:NodeRecordFactory.java

示例10: findSingleNode

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
public static Node findSingleNode(Node baseNode, String xpathExpression, Element nsElement) {
	try {
		Node node = XPathAPI.selectSingleNode(baseNode, xpathExpression, nsElement);
		return node;
	} catch (TransformerException e) {
		throw new RuntimeException("XPath error: " + e.getMessage(), e);
	}
}
 
开发者ID:e-Contract,项目名称:eid-applet,代码行数:9,代码来源:XAdESXLSignatureFacet.java

示例11: tearDown

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
@Override
   protected void tearDown() throws Exception {
	System.out.println("\nRan " + this.countTestCases()
			+ " out of a total of " + this.originalTestCaseCount
			+ " possible test cases\n");

	if (excludesDoc != null) {
		System.out.println("THE FOLLOWING EXCLUSIONS WERE ENFORCED:");
		NodeList allTypes = XPathAPI.selectNodeList(excludesDoc,
				"/descendant::hy:type");
		for (int i = 0; i < allTypes.getLength(); i++) {
			Node typeNode = allTypes.item(i);
			String typeName = typeNode.getAttributes().getNamedItem("id")
					.getNodeValue();
			NodeList allExcludesForType = XPathAPI.selectNodeList(typeNode,
					"descendant::hy:exclude");
			for (int j = 0; j < allExcludesForType.getLength(); j++) {
				Node excludeNode = allExcludesForType.item(j);
				String excName = excludeNode.getAttributes().getNamedItem(
						"id").getNodeValue();
				if (excName.equalsIgnoreCase("all")) {
					excName = "!!!!!!!!!!ALL TESTS!!!!!!!!!!";
				}
				System.out.print(typeName + "::" + excName);
				Node reasonNode = XPathAPI.selectSingleNode(excludeNode,
						"descendant::hy:reason");
				if (reasonNode != null) {
					XObject reason = XPathAPI.eval(reasonNode, "string()");
					System.out.print(" (" + reason.str() + ")");
				}
				System.out.print("\n");
			}// end for all excludes
		}// end for all types
		System.out.println("\n");
	}
	super.tearDown();
}
 
开发者ID:shannah,项目名称:cn1,代码行数:38,代码来源:SomeTests.java

示例12: getRecordData

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
private Element getRecordData(Node record)
throws TransformerException, SAXException, IOException, ParserConfigurationException {
    Node result = XPathAPI.selectSingleNode(record,
            "srw:recordData/*[1]",
            xmlnsEl);
    return toDocument((Element)result).getDocumentElement();
}
 
开发者ID:openpreserve,项目名称:oaicat,代码行数:8,代码来源:XerSRUOAICatalog.java

示例13: configure

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
@Override
  public void configure(Element element) throws Exception {
      super.configure(element);

String version = element.getAttribute("version");
      
if (version == null) {
	String s = XMLUtils.prettyPrintDOM(element);
	EngineException ee = new EngineException("Unable to find version number for the database object \"" + getName() + "\".\nXML data: " + s);
	throw ee;
}

if (VersionUtils.compare(version, "3.1.8") < 0) {
	NodeList properties = element.getElementsByTagName("property");
	Element propValue = (Element) XMLUtils.findNodeByAttributeValue(properties, "name", "httpVariables");

	XMLVector<XMLVector<Long>> httpVariables = null;
	
	Node xmlNode = null;
	NodeList nl = propValue.getChildNodes();
	int len_nl = nl.getLength();
	for (int j = 0 ; j < len_nl ; j++) {
		xmlNode = nl.item(j);
		if (xmlNode.getNodeType() == Node.ELEMENT_NODE) {
			httpVariables = GenericUtils.cast(XMLUtils.readObjectFromXml((Element) xmlNode));
			continue;
		}
	}
	
	XMLVector<XMLVector<Long>> orderedVariables = getOrderedVariables();
	
	int len = orderedVariables.size();
	XMLVector<Long> line;
	for (int i = 0 ; i < len ; i++) {
		line = orderedVariables.get(i);
		if (httpVariables.size()>0) {
			line.add(httpVariables.get(i).get(1));
			line.add(httpVariables.get(i).get(2));
		}
	}
	
	hasChanged = true;
	Engine.logBeans.warn("[HttpTransaction] The object \"" + getName() + "\" has been updated to version 3.1.8");
}


try {
	Node node = XPathAPI.selectSingleNode(element, "property[@name='httpVerb']/java.lang.Integer/@value");
	if (node != null) {
		httpVerb = HttpMethodType.values()[Integer.parseInt(node.getNodeValue())];
		hasChanged = true;
		Engine.logBeans.warn("[HttpTransaction] The object \"" + getName() + "\" has been updated to use the new 'httpVerb' format");
	}
} catch (Throwable t) {
	// ignore migration errors
}
  }
 
开发者ID:convertigo,项目名称:convertigo-engine,代码行数:58,代码来源:AbstractHttpTransaction.java

示例14: configure

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
@Override
public void configure(Element element) throws Exception {
	super.configure(element);
	
       String version = element.getAttribute("version");
       
       if (version == null) {
           String s = XMLUtils.prettyPrintDOM(element);
           EngineException ee = new EngineException(
               "Unable to find version number for the database object \"" + getName() + "\".\n" +
               "XML data: " + s
           );
           throw ee;
       }
       
       if (VersionUtils.compare(version, "4.0.2") < 0) {
       	requestUri = "'" + requestUri + "'";
		hasChanged = true;
		Engine.logBeans.warn("[HttpStatement] The object \"" + getName()+ "\" has been updated to version 4.0.2");
       }
       
	if (VersionUtils.compare(version, "4.2.0") < 0) {
		int len = orderedVariables.size();
		XMLVector<Object> line;
		for (int i = 0 ; i < len ; i++) {
			line = GenericUtils.cast(orderedVariables.get(i));
			if (line.size()>0) {
				// Sets empty description by default
				line.add(1 ,"");
			}
		}
		
		hasChanged = true;
		Engine.logBeans.warn("[HTTPStatement] The object \"" + getName() + "\" has been updated to version 4.2.0");
	}
	
	try {
		Node node = XPathAPI.selectSingleNode(element, "property[@name='httpVerb']/java.lang.Integer/@value");
		if (node != null) {
			httpVerb = HttpMethodType.values()[Integer.parseInt(node.getNodeValue())];
			hasChanged = true;
			Engine.logBeans.warn("[HttpStatement] The object \"" + getName() + "\" has been updated to use the new 'httpVerb' format");
		}
	} catch (Throwable t) {
		// ignore migration errors
	}
}
 
开发者ID:convertigo,项目名称:convertigo-engine,代码行数:48,代码来源:HTTPStatement.java

示例15: testSignExternalUri

import org.apache.xpath.XPathAPI; //导入方法依赖的package包/类
@Test
public void testSignExternalUri() throws Exception {
	// setup
	DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
	documentBuilderFactory.setNamespaceAware(true);
	DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
	Document document = documentBuilder.newDocument();

	SignatureTestFacet signatureFacet = new SignatureTestFacet();
	signatureFacet.addReferenceUri("external-uri");
	XmlSignatureTestService testedInstance = new XmlSignatureTestService(signatureFacet);
	testedInstance.setEnvelopingDocument(document);
	testedInstance.setSignatureDescription("test-signature-description");
	UriTestDereferencer uriDereferencer = new UriTestDereferencer();
	uriDereferencer.addResource("external-uri", "hello world".getBytes());
	testedInstance.setUriDereferencer(uriDereferencer);

	// operate
	DigestInfo digestInfo = testedInstance.preSign(null, null, null, null, null);

	// verify
	assertNotNull(digestInfo);
	LOG.debug("digest info description: " + digestInfo.description);
	assertEquals("test-signature-description", digestInfo.description);
	assertNotNull(digestInfo.digestValue);
	LOG.debug("digest algo: " + digestInfo.digestAlgo);
	assertEquals("SHA-1", digestInfo.digestAlgo);

	TemporaryTestDataStorage temporaryDataStorage = (TemporaryTestDataStorage) testedInstance
			.getTemporaryDataStorage();
	assertNotNull(temporaryDataStorage);
	InputStream tempInputStream = temporaryDataStorage.getTempInputStream();
	assertNotNull(tempInputStream);
	Document tmpDocument = PkiTestUtils.loadDocument(tempInputStream);

	LOG.debug("tmp document: " + PkiTestUtils.toString(tmpDocument));
	Element nsElement = tmpDocument.createElement("ns");
	nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
	Node digestValueNode = XPathAPI.selectSingleNode(tmpDocument, "//ds:DigestValue", nsElement);
	assertNotNull(digestValueNode);
	String digestValueTextContent = digestValueNode.getTextContent();
	LOG.debug("digest value text content: " + digestValueTextContent);
	assertFalse(digestValueTextContent.isEmpty());

	/*
	 * Sign the received XML signature digest value.
	 */
	KeyPair keyPair = PkiTestUtils.generateKeyPair();
	Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
	cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());
	byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestInfo.digestValue);
	byte[] signatureValue = cipher.doFinal(digestInfoValue);

	DateTime notBefore = new DateTime();
	DateTime notAfter = notBefore.plusYears(1);
	X509Certificate certificate = PkiTestUtils.generateCertificate(keyPair.getPublic(), "CN=Test", notBefore,
			notAfter, null, keyPair.getPrivate(), true, 0, null, null, new KeyUsage(KeyUsage.nonRepudiation));

	/*
	 * Operate: postSign
	 */
	testedInstance.postSign(signatureValue, Collections.singletonList(certificate));

	byte[] signedDocumentData = testedInstance.getSignedDocumentData();
	assertNotNull(signedDocumentData);
	Document signedDocument = PkiTestUtils.loadDocument(new ByteArrayInputStream(signedDocumentData));
	LOG.debug("signed document: " + PkiTestUtils.toString(signedDocument));

	NodeList signatureNodeList = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
	assertEquals(1, signatureNodeList.getLength());
	Node signatureNode = signatureNodeList.item(0);

	DOMValidateContext domValidateContext = new DOMValidateContext(
			KeySelector.singletonKeySelector(keyPair.getPublic()), signatureNode);
	domValidateContext.setURIDereferencer(uriDereferencer);
	XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance();
	XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
	boolean validity = xmlSignature.validate(domValidateContext);
	assertTrue(validity);
}
 
开发者ID:e-Contract,项目名称:eid-applet,代码行数:81,代码来源:AbstractXmlSignatureServiceTest.java


注:本文中的org.apache.xpath.XPathAPI.selectSingleNode方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。