我试图在XML文件中的现有属性下添加属性。我一直使用xmlstarted进行编辑,但从未使用它进行更新。如果有人告诉我们如何在这个新的吸引力下添加一个新的属性和元素-
这是我的xml文件的片段-
下面是我通常用xmlstarlet的hel;p编辑子元素时所做的工作-
xmlstarlet edit --inplace -u "/allocations/queue[@name='root']/queue[@name='paas_api_q1']/queue[@name='child1_sq1']/minResources" --value "$value" myfile.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>
</queue>
<queuePlacementPolicy>
<rule create="false" name="specified"/>
<rule name="reject"/>
</queuePlacementPolicy>
</allocations>之后应该是这样..。这里,我在现有的attr - pass_api_q1下添加了一个新属性。
<!-- 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>如有任何帮助/指导,将不胜感激。
发布于 2020-05-22 18:46:19
您可以使用一堆-i/-a/-s来添加新元素(see here),但我认为在tr中使用XSLT会更容易一些。您可以将元素放在另一个文件中,并将其作为参数传入。
例如..。
添加 (fragment.xml)的XML片段
<?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)
<?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命令行
xmlstarlet tr test.xsl -p frag='document("fragment.xml")/*' input.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>发布于 2020-05-26 17:14:29
正如Daniel所指出的,只使用xmlstarlet可能会很乏味,因为它没有复制/粘贴功能,这会使任务变得更简单。作为练习,我尝试了下面的代码,这些代码似乎有效:
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的支持来执行。
https://stackoverflow.com/questions/61954066
复制相似问题