首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用OPENXML解析IIS MetaBase.xml

用OPENXML解析IIS MetaBase.xml
EN

Stack Overflow用户
提问于 2011-04-19 18:03:55
回答 2查看 839关注 0票数 1

我正在尝试将IIS6服务器上的网站列表放入SQL-Server表中。我知道我可以用WMI等来获取它,但这需要在机器上运行一个额外的服务,而我应该能够通过获得一个进程来使用OPENXML解析MetaBase.xml文件来找到信息。

对于那些不熟悉MetaBase.xml的人来说,相关部分看起来有点像下面的内容:

代码语言:javascript
复制
<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来尝试解析它:

代码语言:javascript
复制
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

我看到XML正确地加载到@RawXML中,但从OPENXML查询中什么也得不到。我猜这可能与路径有关,但我已经尝试了许多组合(例如'configuration/MBProperty/IISWebDirectory'),但都没有效果。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-19 18:30:23

您需要将configuration添加到路径中,并将IISWebDirectory更改为IIsWebDirectory,因为XML区分大小写,并且您需要添加xpath_namespaces参数。

代码语言:javascript
复制
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变量。

代码语言:javascript
复制
;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)
票数 3
EN

Stack Overflow用户

发布于 2011-04-19 19:27:09

我将在这里扮演魔鬼倡导者的角色,并建议这是错误的方法。

元数据库文件并不总是最新的。IIS缓存元数据库更新并定期将其刷新到磁盘。我遇到过从使用ADSI或WMI更改属性到在服务器负载下将其刷新到磁盘之间的长达5分钟的延迟。

您说您需要在机器上运行一个额外的服务来收集这些数据。当然,您仍然需要某种进程来从元数据库文件中收集这些数据?

这也是一个坏主意的另一个非常重要的原因是,当你解析这个文件时,你需要自己解析继承的属性。IIS6元数据库的主要技术设计方面之一是属性继承。

例如,如果您正在收集脚本映射,则这是一个继承的属性。除非您已经在站点、虚拟目录或应用程序上显式设置了ScriptMapDefaultDoc (或其他继承属性),否则您需要重新遍历元数据库树才能找到此值。

这是在自食其果。你应该使用API (ADSI,System.DirectoryServices API,即最小阻力路径的API)查询元数据库,而不是直接读取这个文件。相信我,我以前来过这里。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5714683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档