xml - 如何将 XML 片段包含到 XML 文档中

标签 xml powershell doctype

我使用 XML 文件作为我的 PowerShell 脚本的配置文件(基于 rkeithhill.wordpress.com 中找到的博客文章) 。我的一些脚本共享相同的设置,我想包含来自外部 XML 文件的这些设置。我所做的是:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE doc [
<!ENTITY shareddata SYSTEM "shared.xml">
]>
<configuration >
  <appSettings >
    &shareddata;
    <add key="motorcycle" value="Husqvarna TE610" />
    <add key="car" value="Ford Mondeo" />
  </appSettings>
</configuration>

并且shared.xml文件包含(仅一行):

<add key="backhoe" value="Volvo BM 430 Hymas" />

使用以下代码片段加载 XML 并将其打印到控制台:

$config = [xml](get-content $path)
$text = $config.OuterXml
Write-Verbose "[LoadConfig] $text"

输出为:

VERBOSE: [LoadConfig] <?xml version="1.0" standalone="no"?>
<!DOCTYPE doc[
<!ENTITY shareddata SYSTEM "shared.xml">
]>
<configuration><appSettings>&shareddata;
<add key="motorcycle"    value="Husqvarna TE610" />
<add key="car" value="Ford Mondeo" /></appSettings> </configuration>

我加载 XML 的方式不包括 shared.xml 的内容,但它确实解析 DOCTYPE 标记,因为如果我恢复到无效文件,它就会将会失败。


那么,我怎样才能让 PowerShell 完全包含 XML 片段,以便 loadconfig 也能找到我的反铲挖掘机的键和值?


我也尝试过

$Document = ( Select-Xml -Path myfile.xml -XPath / ).Node

但只要我在配置文件中有 &shareddata; 它就不会加载任何内容:

最佳答案

我在 C# 中尝试了你的示例,但它也不起作用。这在 C# 中有效,但是一旦您将 shared.xml 更改为包含 TEST VALUE 值(即只允许简单值,而不是 xml),但它在 PS 中仍然不起作用:

<configuration >
  <appSettings >
    <test>&shareddata;</test>
    <add key="motorcycle" value="Husqvarna TE610" />
    <add key="car" value="Ford Mondeo" />
  </appSettings>
</configuration>

使用此代码:

$doc = new-object System.Xml.XmlDocument
$doc.Load("D:\config.xml")
$doc.configuration.appSettings.add

key        value
---        -----
motorcycle Husqvarna TE610
car        Ford Mondeo

C# 中的相同示例有效:

XmlDocument doc = new XmlDocument();
doc.Load("d:\\config.xml");
var x = doc["configuration"]["appSettings"]["test"];
Console.WriteLine(x.InnerText);

输出

TEST VALUE

Powershell 似乎设置了 doc.XmlResolver = null; 选项来防止与安全相关的问题,您可以在 PS 中看到 $doc.XmlResolver 不返回任何内容。我没有成功通过 $doc.XmlResolver = new-object System.Xml.XmlUrlResolver 手动设置解析器。

现在

您可以使用变量替换来达到效果:

<configuration >
  <appSettings >
    $shared_xml
    <add key="motorcycle" value="Husqvarna TE610" />
    <add key="car" value="Ford Mondeo" />
  </appSettings>
</configuration>

$shared_xml = Get-Content 'D:\shared.xml'
[xml]$config = $ExecutionContext.InvokeCommand.ExpandString((gc $path))

如果您枚举配置 block 中的变量并加载适当的文件,您可以使这变得更容易。这样您就可以事先不知道包含哪些文件。

现在

这一切看起来都很麻烦,除非有一些正常的解决方案来解决解析器问题。但老实说,将配置保留在 XML 中的想法在很多层面上都是错误的。当你可以使用 powershell 配置时为什么要使用 XML:

$config = @{ }
$config.motorcycle = 'Husqvarna TE610'
$config.car = 'Ford Mondeo'

$shared = @{}
$shared.backhoe = "Volvo BM 430 Hymas"

$config + $shared

输出

Name                           Value
----                           -----
backhoe                        Volvo BM 430 Hymas
car                            Ford Mondeo
motorcycle                     Husqvarna TE610

您可以使其遵循“包含”模式,例如:

config.ps1

$config = @{ 
   motorcycle = 'Husqvarna TE610'
   car = 'Ford Mondeo'
}
. shared1.ps1
...
. sharedN.ps1

共享N.ps1

$config.sharedN_cfg1 = 1
$config.sharedN_cfg2 = 2

如果从那时起您确实需要 XML,您可以随后使用 ConvertTo-CliXML 等。

如果您仍然想追求自己的方向,我建议您查看 XInclude (你需要第三次党代表大会才能完成这项工作)。

关于xml - 如何将 XML 片段包含到 XML 文档中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30591166/

相关文章:

facebook - 将 Facebook Connect 及其 xmlns 添加到 (X)HTML5 的正确方法是什么?

html - 将背景图像与 DOCTYPE 一起使用

xml - 是否有使用 XML 的每个功能进行测试的示例 XML 文档?

C# API 库和记录到 PowerShell 的 WriteVerbose()

ios - 如何使用 AFNetworking 发送 XML POST 请求

node.js - Windows 上的 TestCafe 失败,并出现 spawn powershell.exe ENOENT 错误

powershell - FileSystemWatcher 在 PowerShell ISE 中工作,但在运行时不工作

javascript - 使用 JavaScript 读取文档类型

java - 取消选择 ListView 中的项目

json - 从Elasticsearch索引创建Atom或RSS格式的搜索页面,以JSON返回结果