2017-04-04 65 views
0

在下面的XML片段...如何从XML文件中提取与其他字符串共享相同标记的特定字符串?

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xml" href="/static/atom.xsl"?> 
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:s="http://dev.splunk.com/ns/rest" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"> 
    <title>serverclients</title> 
    <id>https://splfwdprw2:8089/servicesNS/nobody/search/deployment/server/clients</id> 
    <updated>2017-04-04T16:14:04-04:00</updated> 
    <generator build="f3e41e4b37b2" version="6.3.1"/> 
    <author> 
    <name>Splunk</name> 
    </author> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/_acl" rel="_acl"/> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/countClients_by_machineType" rel="countClients_by_machineType"/> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/countRecentDownloads" rel="countRecentDownloads"/> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/getMatchingAppsForClient_dryRun" rel="getMatchingAppsForClient_dryRun"/> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/preview" rel="preview"/> 
    <opensearch:totalResults>1</opensearch:totalResults> 
    <opensearch:itemsPerPage>18446744073709551615</opensearch:itemsPerPage> 
    <opensearch:startIndex>0</opensearch:startIndex> 
    <s:messages/> 
    <entry> 
    <title>00031e8f6c883544b8079037c5eba9ec</title> 
    <id>https://splfwdprw2:8089/servicesNS/nobody/search/deployment/server/clients/00031e8f6c883544b8079037c5eba9ec</id> 
    <updated>2017-04-04T16:14:04-04:00</updated> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/00031e8f6c883544b8079037c5eba9ec" rel="alternate"/> 
    <author> 
     <name>system</name> 
    </author> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/00031e8f6c883544b8079037c5eba9ec" rel="list"/> 
    <link href="/servicesNS/nobody/search/deployment/server/clients/00031e8f6c883544b8079037c5eba9ec" rel="remove"/> 
    <content type="text/xml"> 
     <s:dict> 
     <s:key name="applications"> 
      <s:dict> 
      <s:key name="all_deploymentclient"> 
       <s:dict> 
       <s:key name="action">Phonehome</s:key> 
       <s:key name="archive">/opt/splunk/var/run/tmp/all_deploymentclient/all_deploymentclient-1491320471.bundle</s:key> 
       <s:key name="checksum">0</s:key> 
       <s:key name="excludeFromUpdate"></s:key> 
       <s:key name="failedReason"></s:key> 
       <s:key name="issueReload">0</s:key> 
       <s:key name="restartSplunkWeb">0</s:key> 
       <s:key name="restartSplunkd">1</s:key> 
       <s:key name="result">Ok</s:key> 
       <s:key name="serverclasses"> 
        <s:list> 
        <s:item>all_deploymentclient</s:item> 
        </s:list> 
       </s:key> 
       <s:key name="size">10240</s:key> 
       <s:key name="stateOnClient">enabled</s:key> 
       <s:key name="timestamp">Tue Apr 4 11:42:54 2017</s:key> 
       </s:dict> 
      </s:key> 
      <s:key name="all_fwd_outputs_18indexers"> 
       <s:dict> 
       <s:key name="action">Phonehome</s:key> 
       <s:key name="archive">/opt/splunk/var/run/tmp/all_fwd/all_fwd_outputs_18indexers-1491320471.bundle</s:key> 
       <s:key name="checksum">0</s:key> 
       <s:key name="excludeFromUpdate"></s:key> 
       <s:key name="failedReason"></s:key> 
       <s:key name="issueReload">0</s:key> 
       <s:key name="restartSplunkWeb">0</s:key> 
       <s:key name="restartSplunkd">1</s:key> 
       <s:key name="result">Ok</s:key> 
       <s:key name="serverclasses"> 
        <s:list> 
        <s:item>all_fwd</s:item> 
        </s:list> 
       </s:key> 
       <s:key name="size">10240</s:key> 
       <s:key name="stateOnClient">enabled</s:key> 
       <s:key name="timestamp">Tue Apr 4 11:42:54 2017</s:key> 
       </s:dict> 
      </s:key> 

...我试图提取任何“S:键名=”出现在下面的第一级字符串“S:键名=”应用程序“标签,在这个例子中,我想要提取的字符串是”all_deploymentclient“和”all_fwd_outputs_18indexers“,如果额外的字符串出现在同一级别,我想要捕获这些字符串。我正在使用xml_grep,但我不确定如何定义参数以获得所需的结果(因为有多个“s:key name =”标记的实例,其中一些实例可用作标题和有价值的其他人分配给他们)。

所以,当这一切都说过和做过,提取输出这个例子应该是:

all_deploymentclient 
all_fwd_outputs_18indexers 

我怎样才能做到这一点?是否需要另一个实用工具(如xpath)?

+0

“XML片段”是否完整?前缀's'是否在任何地方? (像'xmlns:s =“一些命名空间uri”'。) –

回答

0

考虑到@MichaelKay和@knb提供的信息,我能够确定一个解决方案。最后我用xmlstarlet得到我所需要的信息如下:

xmlstarlet sel -T -t -m "//*[local-name()='key'][@name='applications']/*/*/@name" -v . -n <XML filename> 

这产生了以下的输出:

all_deploymentclient 
all_fwd_outputs_18indexers 

感谢大家对他们的贡献!

1

也许尝试这第一个(快速和肮脏的方法来替代s:空间前缀):

cat /var/tmp/content.xml | sed 's/s://g' > cat /var/tmp/content2.xml 

然后尝试

xmllint --xpath "//key[@name='all_deploymentclient' or @name='all_fwd_outputs_18indexers']/@name" /var/tmp/content2.xml \ 
| sed "s| name|\nname|g; s/name=\"//; s/\"\$//" 
+0

感谢您的输入!当我阅读你的回复时,我意识到我没有足够清楚地描述我的问题,所以我已经相应地编辑了我的问题的描述。 –

1

当你做任何的搜索任何类型的数据源中的,仅仅知道实际数据是什么(如果您知道,您不需要搜索它)是不够的:您需要知道它可能与示例所示的不同。

所以我们必须看看你对问题的描述:“s:key name =”出现在“s:key name =”应用程序“标签”之后的缩进中的字符串,试着理解你的意思通过它。

  • 通过缩进,你字面意思是分页布局,还是这是你谈论XML数据模型的树结构的方式?

  • 当你说“之后”时,我们是否将这个(根据你的例子)解释为“第一后裔”元素,即我们在树中行走时遇到的第一个匹配的后代?

我们可以假设这些“第一后代”总是从原始节点(即孙辈?)向下两级。如果是这样,XPath的解决方案就是

//s:key[@name="applications"]/*/*/@name 

但是,如果“第一后裔”可能是在不同的深度,然后就变得相当困难,而解决方案可能还取决于您所使用的XPath的版本。所以我们需要更多的信息。

我不知道xml_grep能够做什么。

+0

你已经非常广泛地分解了我的问题。我只是修改了XML代码片段以包含代码的开始部分(为了让每个人都能看到完整的图片)。回答@MichaelKay提出的问题:“缩进”是我描述代码中每个标签级别的笨拙方式。所以,如果''是“父”,那么''将是“子”(下一级)。孩子的水平是我有兴趣收集的;我不会再下去了。 –

相关问题