首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >xmlstartlet脚本,用于在属性下添加属性和元素

xmlstartlet脚本,用于在属性下添加属性和元素
EN

Stack Overflow用户
提问于 2020-05-22 11:32:30
回答 2查看 226关注 0票数 0

我试图在XML文件中的现有属性下添加属性。我一直使用xmlstarted进行编辑,但从未使用它进行更新。如果有人告诉我们如何在这个新的吸引力下添加一个新的属性和元素-

这是我的xml文件的片段-

下面是我通常用xmlstarlet的hel;p编辑子元素时所做的工作-

代码语言:javascript
复制
xmlstarlet edit  --inplace -u "/allocations/queue[@name='root']/queue[@name='paas_api_q1']/queue[@name='child1_sq1']/minResources" --value "$value" myfile.xml

在此之前-

代码语言:javascript
复制
<?xml version="1.0"?>
<allocations>
  <queue name="root">
    <aclSubmitApps> bddbagrp,mapr</aclSubmitApps>
    <aclAdministerApps> bddbagrp,root,mapr,trmte_id</aclAdministerApps>
    <schedulingPolicy>drf</schedulingPolicy>
    <defaultMinSharePreemptionTimeout>60</defaultMinSharePreemptionTimeout>
    <fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
    <queue name="paas_api_q1">
      <minResources>90000 mb,15 vcores,2 disks</minResources>
      <maxResources>135000 mb,22 vcores,3 disks</maxResources>
      <queue name="child1_sq1">
        <minResources>66000 mb,11 vcores,2 disks</minResources>
        <maxResources>264000 mb,44 vcores,8 disks</maxResources>
        <aclSubmitApps> paas_opsauto_admin_unix</aclSubmitApps>
        <aclAdministerApps> paas_opsauto_admin_unix</aclAdministerApps>
        <label>allnodes||balanced</label>
      </queue>
    </queue>
  </queue>
  <queuePlacementPolicy>
    <rule create="false" name="specified"/>
    <rule name="reject"/>
  </queuePlacementPolicy>
</allocations>

之后应该是这样..。这里,我在现有的attr - pass_api_q1下添加了一个新属性。

代码语言:javascript
复制
<!-- language: lang-xml -->
<?xml version="1.0"?>
<allocations>
  <queue name="root">
    <aclSubmitApps> bddbagrp,mapr</aclSubmitApps>
    <aclAdministerApps> bddbagrp,root,mapr,trmte_id</aclAdministerApps>
    <schedulingPolicy>drf</schedulingPolicy>
    <defaultMinSharePreemptionTimeout>60</defaultMinSharePreemptionTimeout>
    <fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
    <queue name="paas_api_q1">
      <minResources>90000 mb,15 vcores,2 disks</minResources>
      <maxResources>135000 mb,22 vcores,3 disks</maxResources>
      <queue name="child1_sq1">
        <minResources>66000 mb,11 vcores,2 disks</minResources>
        <maxResources>264000 mb,44 vcores,8 disks</maxResources>
        <aclSubmitApps> paas_opsauto_admin_unix</aclSubmitApps>
        <aclAdministerApps> paas_opsauto_admin_unix</aclAdministerApps>
        <label>allnodes||balanced</label>
      </queue>
      <queue name="child2_sq1">
        <minResources>66000 mb,11 vcores,2 disks</minResources>
        <maxResources>132000 mb,22 vcores,4 disks</maxResources>
        <aclSubmitApps> paas_opsauto_admin_unix</aclSubmitApps>
        <aclAdministerApps> paas_opsauto_admin_unix</aclAdministerApps>
        <label>allnodes||balanced</label>
      </queue>
    </queue>
  </queue>
  <queuePlacementPolicy>
    <rule create="false" name="specified"/>
    <rule name="reject"/>
  </queuePlacementPolicy>
</allocations>

如有任何帮助/指导,将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-22 18:46:19

您可以使用一堆-i/-a/-s来添加新元素(see here),但我认为在tr中使用XSLT会更容易一些。您可以将元素放在另一个文件中,并将其作为参数传入。

例如..。

添加 (fragment.xml)的XML片段

代码语言:javascript
复制
<?xml version="1.0"?>
<queue name="child2_sq1">
    <minResources>66000 mb,11 vcores,2 disks</minResources>
    <maxResources>132000 mb,22 vcores,4 disks</maxResources>
    <aclSubmitApps> paas_opsauto_admin_unix</aclSubmitApps>
    <aclAdministerApps> paas_opsauto_admin_unix</aclAdministerApps>
    <label>allnodes||balanced</label>
</queue>

XSLT (test.xsl)

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="frag"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!--If you wanted to make this stylesheet reusable, you could pass a new
  value in for the "match" attribute by selecting this template by its
  "name" value (@name='target').-->
  <xsl:template match="queue[@name='paas_api_q1']" name="target">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <xsl:copy-of select="$frag"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

xmlstarlet命令行

代码语言:javascript
复制
xmlstarlet tr test.xsl -p frag='document("fragment.xml")/*' input.xml

输出

代码语言:javascript
复制
<?xml version="1.0"?>
<allocations>
  <queue name="root">
    <aclSubmitApps> bddbagrp,mapr</aclSubmitApps>
    <aclAdministerApps> bddbagrp,root,mapr,trmte_id</aclAdministerApps>
    <schedulingPolicy>drf</schedulingPolicy>
    <defaultMinSharePreemptionTimeout>60</defaultMinSharePreemptionTimeout>
    <fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
    <queue name="paas_api_q1">
      <minResources>90000 mb,15 vcores,2 disks</minResources>
      <maxResources>135000 mb,22 vcores,3 disks</maxResources>
      <queue name="child1_sq1">
        <minResources>66000 mb,11 vcores,2 disks</minResources>
        <maxResources>264000 mb,44 vcores,8 disks</maxResources>
        <aclSubmitApps> paas_opsauto_admin_unix</aclSubmitApps>
        <aclAdministerApps> paas_opsauto_admin_unix</aclAdministerApps>
        <label>allnodes||balanced</label>
      </queue>
      <queue name="child2_sq1">
        <minResources>66000 mb,11 vcores,2 disks</minResources>
        <maxResources>132000 mb,22 vcores,4 disks</maxResources>
        <aclSubmitApps> paas_opsauto_admin_unix</aclSubmitApps>
        <aclAdministerApps> paas_opsauto_admin_unix</aclAdministerApps>
        <label>allnodes||balanced</label>
      </queue>
    </queue>
  </queue>
  <queuePlacementPolicy>
    <rule create="false" name="specified"/>
    <rule name="reject"/>
  </queuePlacementPolicy>
</allocations>
票数 2
EN

Stack Overflow用户

发布于 2020-05-26 17:14:29

正如Daniel所指出的,只使用xmlstarlet可能会很乏味,因为它没有复制/粘贴功能,这会使任务变得更简单。作为练习,我尝试了下面的代码,这些代码似乎有效:

代码语言:javascript
复制
xmlstarlet ed  
     -a "//queue/queue[@name='paas_api_q1']/queue"
     -t elem -n queue -v "$(xmlstarlet sel  -t -m //queue/queue[@name]/*/* -c . myfile.xml)"
     -i "//queue[@name='paas_api_q1']//queue[not(@name)]" --type attr --name "name" -v "child2_sq1" \
   myfile.xml | xmlstarlet unesc

基本上,它在适当的位置创建一个新节点,创建原始节点的副本(使用变量),将副本插入到新节点的值中,向新节点添加一个属性和一个值,最后从原始节点的副本中取消转义标记。

就像我说的,只是一个练习..。

虽然我还没有试过,但我猜想这个任务也可以使用xmlstarlet、xidel及其对xquery的支持来执行。

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

https://stackoverflow.com/questions/61954066

复制
相关文章

相似问题

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