📄 xsdpars.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//+----------------------------------------------------------------------------
//
//
// File: xsdpars.cpp
//
// Contents:
//
// implementation file
//
// xsdparser implemenation
//
//
//-----------------------------------------------------------------------------
#include "headers.h"
#include "soapmapr.h"
#include "typemapr.h"
#include "xsdpars.h"
#ifdef UNDER_CE
#include "strsafe.h"
#endif
typedef struct _XSDSchemaEntries
{
schemaRevisionNr m_enSchemaRevision;
TCHAR * m_schemaNS;
TCHAR * m_schemaInstanceNS;
TCHAR * m_schemaInstanceXPATH;
} XSDSchemaEntries;
const XSDSchemaEntries g_arrSchemaEntries[] =
{
{
enSchema2001,
L"http://www.w3.org/2001/XMLSchema",
L"http://www.w3.org/2001/XMLSchema-instance",
L"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"
},
{
enSchema2000,
L"http://www.w3.org/2000/10/XMLSchema",
L"http://www.w3.org/2000/10/XMLSchema-instance",
L"xmlns:xsi='http://www.w3.org/2000/10/XMLSchema-instance'"
},
{
enSchema1999,
L"http://www.w3.org/1999/XMLSchema",
L"http://www.w3.org/1999/XMLSchema-instance",
L"xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'"
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: _XSDFindURIForPrefix(IXMLDOMNode *pStartNode, TCHAR *pchPrefix, BSTR * pbstrURI)
//
// parameters:
// pStartNode -> the DOM node to start looking outwards from
// pchPrefix -> the namespace prefix in the QNAME (like "my:something", my is the prefix)
// pbstrURI -> the URI namespace (out)
//
// description:
// takes a startnode and searches for the XMLNS:PREFIX attribute on all nodes outwards
// returns:
// S_OK = found the namespace
// E_FAIL = namespace not found
// E_INVALIDARG = arguments are wrong
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT _XSDFindURIForPrefix(IXMLDOMNode *pStartNode, TCHAR *pchPrefix, BSTR * pbstrURI)
{
HRESULT hr = E_FAIL;
TCHAR achBuffer[ONEK+1];
CAutoRefc<IXMLDOMNode> pCurrentNode;
CAutoRefc<IXMLDOMNode> pNextNode;
bool bFound=false;
if (!pStartNode || !pbstrURI || !pchPrefix)
{
hr = E_INVALIDARG;
goto Cleanup;
}
assign(&pCurrentNode, pStartNode);
// create the attribute we are looking for
if (wcslen(pchPrefix)==0)
{
// empty prefix, no URI, valid case
wcscpy(achBuffer, _T("xmlns"));
}
else
{
#ifdef UNDER_CE
hr = StringCbPrintf(achBuffer, (sizeof(TCHAR) * ONEK+1), _T("xmlns:%s"), pchPrefix);
if(FAILED(hr))
{
goto Cleanup;
}
#else
swprintf(achBuffer, _T("xmlns:%s"), pchPrefix);
#endif
}
while (!bFound)
{
hr = _WSDLUtilFindAttribute(pCurrentNode, achBuffer, pbstrURI);
if (hr == E_FAIL)
{
hr = pCurrentNode->get_parentNode(&pNextNode);
if (hr == S_OK && pNextNode)
{
pCurrentNode.Clear();
assign(&pCurrentNode, (IXMLDOMNode*)pNextNode);
pNextNode.Clear();
}
else
{
hr = E_FAIL;
goto Cleanup;
}
}
else
{
bFound = true;
}
}
Cleanup:
return(hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT _XSDLFindTargetSchema(TCHAR *pchURI, IXMLDOMNode *pDom, IXMLDOMNode **ppSchemaNode)
//
// parameters:
// pchURI -> URI for the targetnamespace attribute
// pDom => document to search
// ppSchemanode -> out -> schemanode to return
// description:
// searches for a schema with the specified TNS
// returns:
// S_OK : found
// E_FAIL : not found
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT _XSDLFindTargetSchema(TCHAR *pchURI, IXMLDOMNode *pDom, IXMLDOMNode **ppSchemaNode)
{
HRESULT hr;
CAutoFormat autoFormat;
if (pchURI)
{
CHK(autoFormat.sprintf(_T("//def:types/schema:schema[@targetNamespace=\"%s\"]"), pchURI));
}
else
{
CHK(autoFormat.copy(_T("//def:types/schema:schema[not(@targetNamespace)]")));
}
hr = _XPATHUtilFindNodeFromRoot(pDom, &autoFormat, ppSchemaNode);
Cleanup:
return(hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT _XSDFindTargetNameSpace(IXMLDOMNode *pStartNode, BSTR *pbstrURI)
//
// parameters:
// pSchemanode -> starting schema element
// BSTR * pbstrURI -> out -> targetNamespace
// description:
// searches node upwards until it finds targetnamespace declaration
// returns:
// S_OK : found
// E_FAIL : not found
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT _XSDFindTargetNameSpace(IXMLDOMNode *pStartNode, BSTR *pbstrURI)
{
HRESULT hr = E_FAIL;
CAutoRefc<IXMLDOMNode> pCurrentNode;
CAutoRefc<IXMLDOMNode> pNextNode;
bool bFound=false;
if (!pStartNode || !pbstrURI )
{
hr = E_INVALIDARG;
goto Cleanup;
}
assign(&pCurrentNode, pStartNode);
while (!bFound)
{
hr = _WSDLUtilFindAttribute(pCurrentNode, L"targetNamespace", pbstrURI);
if (hr == E_FAIL)
{
hr = pCurrentNode->get_parentNode(&pNextNode);
if (hr == S_OK && pNextNode)
{
pCurrentNode.Clear();
assign(&pCurrentNode, (IXMLDOMNode*)pNextNode);
pNextNode.Clear();
}
else
{
hr = E_FAIL;
goto Cleanup;
}
}
else
{
bFound = true;
}
}
Cleanup:
return(hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: TCHAR * _XSDIsPublicSchema(TCHAR *pchURI)
//
// parameters:
// pchURI -> URI to check
// description:
// verifies if the URI is a public XSD schema
// returns:
// global pointer to public schema def
// 0 if not
/////////////////////////////////////////////////////////////////////////////////////////////////////////
schemaRevisionNr _XSDIsPublicSchema(TCHAR *pchURI)
{
if (pchURI)
{
for (int i = 0; i < countof(g_arrSchemaEntries); i++)
{
if (wcscmp(pchURI, g_arrSchemaEntries[i].m_schemaNS)==0)
{
return (g_arrSchemaEntries[i].m_enSchemaRevision) ;
}
}
}
return (enSchemaInvalid);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT _XSDFindRevision(IXMLDOMNode *pNode, schemaRevisionNr *pRevisionNr)
//
// parameters:
// pNode -> node in a document with a schema definition
// description:
// schecks for schemas, returns revisionnr of schema
// when NO node is passed in, return latest schema revision
// returns:
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT _XSDFindRevision(IXMLDOMNode *pNode, schemaRevisionNr *pRevisionNr)
{
CAutoRefc<IXMLDOMDocument2> pDoc;
CAutoRefc<IXMLDOMDocument> pTemp;
HRESULT hr;
if (!pNode)
{
*pRevisionNr = enSchemaLast;
hr = S_OK;
goto Cleanup;
}
CHK ( pNode->get_ownerDocument(&pTemp));
if (pTemp == NULL)
{
// we are already at the root and pDoc is NULL (msxml behavior)
CHK(pNode->QueryInterface(IID_IXMLDOMDocument2, (void **)&pDoc));
}
else
{
CHK ( pTemp->QueryInterface(IID_IXMLDOMDocument2, (void **)&pDoc));
}
CHK(_XSDFindRevision(pDoc, pRevisionNr));
Cleanup:
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// function: HRESULT _XSDFindRevision(IXMLDOMDocument2 *pDocument, schemaRevisionNr *pRevisionNr)
//
// parameters:
// DomDocument -> document with schema definitons
// description:
// schecks for schemas, returns revisionnr of schema
// returns:
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT _XSDFindRevision(IXMLDOMDocument2 *pDocument, schemaRevisionNr *pRevisionNr)
{
HRESULT hr=S_OK;
CAutoRefc<IXMLDOMSchemaCollection> pIXMLDOMSchemaCollection=0;
LONG lLength;
CAutoBSTR bstrTemp;
#ifdef UNDER_CE
long lIndex;
#endif
CHK(pDocument->get_namespaces(&pIXMLDOMSchemaCollection));
CHK(pIXMLDOMSchemaCollection->get_length(&lLength));
#ifndef UNDER_CE
for(long lIndex=0; lIndex < lLength; lIndex++)
#else
for(lIndex=0; lIndex < lLength; lIndex++)
#endif
{
CHK(pIXMLDOMSchemaCollection->get_namespaceURI(lIndex, &bstrTemp));
*pRevisionNr = _XSDIsPublicSchema(bstrTemp);
if (*pRevisionNr != enSchemaInvalid)
{
break;
}
bstrTemp.Clear();
}
if (lIndex>=lLength)
{
// did not find a schema namespace, invalid
hr = E_INVALIDARG;
}
Cleanup:
return (hr);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -