【问题标题】:matching syntax issue匹配语法问题
【发布时间】:2015-12-17 00:05:12
【问题描述】:

我正在解析一个大型 XML 文件以查找某些内容,例如

$matches = [regex]::matches($content, '(<ac:structured-macro.+?ac:name="jira".+?</ac:structured-macro>)'

即返回以 &lt;ac:structured-macro&gt; 开头和结尾的部分,其中包含“jira”。

我发现的也是其他记录,例如

<ac:structured-macro blah blah </ac:structured-macro>
<ac:structured-macro blah ac:name="jira" blah </ac:structured-macro>

我希望它只找到包含“jira”的那些。

  1. 如果你找到结尾“ac:structured-macro”而没有找到“jira”部分重新开始搜索,我怎么告诉它?

  2. 一旦我找到这个,我需要在这个匹配中获取零件。 .+?(item1).+?(item2) 是语法吗? (类似于 C#)

源样本:

<ac:structured-macro ac:name="jira">
    <ac:parameter ac:name="columns">key,summary,type,created,updated,due,assignee,reporter,priority,status,resolution</ac:parameter>
    <ac:parameter ac:name="server">JIRA (site.atlassian.net)</ac:parameter>
    <ac:parameter ac:name="serverId">72f475d9-a9b2</ac:parameter>
    <ac:parameter ac:name="jqlQuery">project = PLATFORM AND issuetype in (Bug, Question, Story) AND fixVersion = 1.12.1 AND component = &quot;UI Framework&quot;   </ac:parameter>
    <ac:parameter ac:name="maximumIssues">20</ac:parameter>
</ac:structured-macro>

【问题讨论】:

  • 请仅将 sn-ps 用于实际可运行的 javascript、css 或 html。它们不用于其他任何用途。
  • 注意:我应该补充一点,结构内部还有许多其他项目,所以 [^
  • @GregBRoberts 编辑问题以包含代码;除此之外,请停止对问题表示感谢;它分散了问题的注意力,并不是真正被这里接受的东西。最后,您可以通过在块前添加四个空格来格式化代码。有关签名/感谢/称呼的更多信息,请参阅here
  • 那我建议转换成xml并解析。检查这篇文章stackoverflow.com/a/18035655/5290909 ...如果你坚持使用正则表达式,要匹配嵌套元素,你必须使用balancing groups

标签: regex xml powershell


【解决方案1】:

如 cmets 中所述 - 不要对 XML 使用正则表达式!

相反,使用 .NET 的内置功能对其进行解析并使用它:

$XmlDoc = [xml](Get-Content .\largefile.xml) 

现在,$XmlDoc 变量包含一个实时的XmlDocument,我们可以通过编程方式检查和修改它(使用XPath),而不仅仅是纯文本

根据您简短的 sn-ps 的内容,我猜这个大型 xml 文件是一个 XSLT 模板,其中包含用于 Confluence 的 JIRA 宏。

由于 Confluence 使用命名空间前缀 ac - 我们需要创建命名空间管理器以便使用 XPath 查询文档:

$XmlNSMgr = New-Object System.Xml.XmlNamespaceManager $XsltDoc.NameTable
$XmlNSMgr.AddNamespace("xsl","http://www.w3.org/1999/XSL/Transform")
$XmlNSMgr.AddNamespace("ac","http://www.atlassian.com/schema/confluence/4/ac/")

现在您可以使用SelectNodes() 方法和XPath 表达式选择所需的节点:

$XPathExpression = '//ac:structured-macro'
$MacroNodes = $XmlDoc.SelectNodes($XPathExpression, $XmlNSMgr)

$MacroNodes 现在是文档中所有&lt;ac:structured-macro&gt; 节点的集合。

要仅选择存在ac:name="jira" 属性的节点,请在XPath 表达式中添加一个子句:

$XPathExpression = '//ac:structured-macro[@ac:name = "jira"]'
$JiraMacroNodes = $XmlDoc.SelectNodes($XPathExpression, $XmlNSMgr)

您甚至可以编辑节点,当您保存编辑时文档将被修改:

$JiraMacroNodes |ForEach-Object {
    $_.SetAttribute("attrName","newValue")
}
$XmlDoc.Save("C:\path\to\new.xslt")

【讨论】:

  • 谢谢马蒂亚斯和马里亚诺
  • 试过了,但没有找到。我认为这个问题与其中许多宏有关 ![CDATA ?例如本页列出了1.12.0版本的功能发布,以及包含的组件模块版本。

  • @GregBRoberts “没有命中”是什么意思?
  • 最火的选择节点后的中断显示未选择任何项目。在 cmets 中格式化数据时遇到问题。我想发更多,但系统不让我发帖。
  • NB:使用 $XPathExpression = '//object[@class="ReferralLink"]' 导致许多条目,因此数据在那里,但我认为问题是元素在 [CDATA
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
相关资源
最近更新 更多