2011-04-19 4 views
1

IIS 6 서버의 웹 사이트 목록을 SQL Server 테이블로 가져 오려고합니다. WMI 등으로 얻을 수는 있지만 상자에 추가 서비스가 있어야합니다. 반면 OPENXML을 사용하여 MetaBase.xml 파일을 구문 분석하는 데 proc을 사용하여 정보를 찾을 수 있어야합니다.OPENXML을 사용하여 IIS MetaBase.xml을 구문 분석

<configuration xmlns="urn:microsoft-catalog:XML_Metabase_V64_0"> 
    <MBProperty> 
    <IIsWebDirectory Location="/LM/W3SVC/1/ROOT/MySite1" AppFriendlyName="MySite1" AppIsolated="2" AppPoolId="MySite1" AppRoot="/LM/W3SVC/1/ROOT/MySite1" DontLog="TRUE">  
    </IIsWebDirectory> 
    <IIsWebDirectory Location="/LM/W3SVC/1/ROOT/MySite2" AppFriendlyName="MySite2" AppIsolated="2" AppPoolId="MySite2" AppRoot="/LM/W3SVC/1/ROOT/MySite2" DontLog="TRUE">  
    </IIsWebDirectory> 
    </MBProperty> 
</configuration> 

나는 그것을 구문 분석하려고 다음과 같은 SQL을 사용하고 있습니다 :

DECLARE @XMLPath VARCHAR(MAX) 
SELECT @XMLPath = 'C:\Temp\MetaBase.xml' 

DECLARE @RawXML XML, @sql NVARCHAR(4000), @params NVARCHAR(4000), @handle INT 
SELECT @sql = N'SELECT @res = (SELECT * FROM OPENROWSET (BULK '''+ @XMLPath +''', SINGLE_BLOB)x)' 
SELECT @params = N'@res XML OUTPUT' 
EXEC sp_executesql @sql, @params, @res = @RawXML OUTPUT 

SELECT @RawXML 

EXEC sp_xml_preparedocument @handle OUTPUT, @RawXML 
SELECT * 
FROM OPENXML(@handle, 'MBProperty/IISWebDirectory', 3) WITH (AppFriendlyName VARCHAR(800), Location VARCHAR(800), AppRoot VARCHAR(800), AppPoolId VARCHAR(800), DefaultDoc VARCHAR(800)) 
EXEC sp_xml_removedocument @handle 
을 MetaBase.xml의에 익숙하지 않은 당신의 사람들을 위해

, 관련 부분은 약간 다음과 같이

XML이 @RawXML에 올바르게로드되었지만 OPENXML 쿼리에서 아무 것도 얻지 못합니다. 아마도 그 경로와 관련이있는 것으로 추측하고 있지만 조합 (예 : 'configuration/MBProperty/IISWebDirectory')을 사용해 보았습니다.

답변

3

경로에 configuration을 추가하고 XML이 대/소문자를 구분하므로 xpath_namespaces 매개 변수를 추가해야하므로 IISWebDirectory를 IIsWebDirectory로 변경해야합니다.

EXEC sp_xml_preparedocument @handle OUTPUT, @RawXML, '<root xmlns:ns="urn:microsoft-catalog:XML_Metabase_V64_0" />' 

SELECT * 
FROM OPENXML(@handle, 'ns:configuration/ns:MBProperty/ns:IIsWebDirectory', 3) WITH 
    (AppFriendlyName VARCHAR(800), 
    Location VARCHAR(800), 
    AppRoot VARCHAR(800), 
    AppPoolId VARCHAR(800), 
    DefaultDoc VARCHAR(800)) 
EXEC sp_xml_removedocument @handle 

또는 XML 변수를 직접 쿼리 할 수 ​​있습니다.

;with xmlnamespaces ('urn:microsoft-catalog:XML_Metabase_V64_0' as ns) 
select 
    n.i.value('@AppFriendlyName', 'varchar(800)') as AppFriendlyName, 
    n.i.value('@Location', 'varchar(800)') as Location, 
    n.i.value('@AppRoot', 'varchar(800)') as AppRoot, 
    n.i.value('@AppPoolId', 'varchar(800)') as AppPoolId, 
    n.i.value('@DefaultDoc', 'varchar(800)') as DefaultDoc 
from @RawXML.nodes('ns:configuration/ns:MBProperty/ns:IIsWebDirectory') as n(i) 
+0

이 접근법은 많은 수준에서 결함이 있습니다. 내 대답을 보라. – Kev

+0

기술적으로 그것이 내 문제를 해결했기 때문에이 하나를 수락했습니다 :) – Skrealin

3

나는 여기에 악마 옹호자 역할을 할 것이며 이것이 잘못된 접근이라고 제안 할 것입니다.

메타베이스 파일이 항상 최신이 아닙니다. IIS는 메타베이스 업데이트를 캐시하고 주기적으로 디스크로 플러시합니다. ADSI 또는 WMI를 사용하여 속성을 변경하는 동안 최대 5 분의 지연이 발생했으며 서버가로드 될 때 디스크로 플러시됩니다.

이 데이터를 수집하기 위해 컴퓨터에서 실행중인 추가 서비스가 필요하다고 말합니다. 메타 데이터 파일에서이 데이터를 수집하려면 어떤 종류의 프로세스가 필요합니까?

이 또한 나쁜 생각 인 또 다른 중요한 이유는이 파일을 구문 분석 할 때 상속 된 속성을 직접 해결해야하기 때문입니다. IIS6 메타베이스의 주요 기술 설계 측면 중 하나는 속성 상속입니다.

예를 들어, 스크립트 맵을 수집하는 경우 이는 상속 된 속성입니다. 명시 적으로 ScriptMap 또는 DefaultDoc (또는 다른 상속 된 속성)을 사이트, 가상 디렉터리 또는 응용 프로그램에 명시 적으로 설정하지 않은 경우이 값을 찾으려면 메타베이스 트리를 다시 워크 플로해야합니다.

그건 네가 직접 막대를 만들고있어. 은이 파일을 직접 읽지 않고 메타베이스를 쿼리하기 위해 API (ADSI, System.DirectoryServices [가장 저항력이 약한 API] 또는 WMI)를 사용해야합니다. 날 믿어. 나는 여기 전에왔다.

+1

답장을 +1하십시오. OP보다 내 것보다 도움이 될 가능성이 큽니다. BTW, 나는 IIS 메타베이스에 대해 아무것도 모르고 있지만 SQL Server에서 XML을 구문 분석하는 것에 대해 조금 알고 있습니다. –

+1

@mikael - 나는 당신의 대답을 좋아한다. 나는 또한 좋은 SQL XML 파싱의 도전에 감사한다. :) 그러나 나는 또한 OP가 자신의 문제를 이런 방식으로 해결하도록 장려하고 싶지 않습니다. – Kev

+0

감사합니다. Kev, 저는 (SQL 자체를 수정하는 것 이외에) 제 접근법에 대해 누군가 의견을 제시하기를 바랬습니다.이것을 게시 한 후 나는 망치로 못을 찾아 다니고 있을지도 모른다고 생각했다. 질문에 대한 답변 : 1) 질문에 사용 된 로컬 경로 대신 네트워크 경로를 사용하여 파일을 가져올 수 있습니다. 2) 매일 실행되지만 웹 앱이 너무 자주 공개되어 매주 실행될 수 있습니다. 3) 필요한 유일한 데이터는 이름과 URL입니다. http : // @ host/@ AppFriendlyName/@ DefaultDoc을 사용하여 URL을 추측 할 수 있습니다. – Skrealin