你們會如何在一堆 XML 文件中的某些標籤後面添加一行?解決方案可以基於 unix 工具的使用,或命名一個文字編輯器或實用程序,讓我可以快速輕鬆地完成此操作。我有 60 多個文件需要編輯。
例如我有以下 XML:
<Node disablePersistence="true">
<Name>Mapper</Name>
<Action>
<Class-Name>com.test.component.Mapper</Class-Name>
<Param name="output_url" value="constant:file:///output.xml"/>
<Param name="xml_url" value="constant:file:///input.xml"/>
<Param name="xsl_url" value="constant:file:///template.xsl"/>
</Action>
<Next-Node>ComposeMessage</Next-Node>
</Node>
首先,我需要搜尋標籤 Node。然後我需要搜尋標籤 Name = Mapper。然後搜尋標籤 Action。然後搜尋標籤Param。然後我們需要在 Param 的所有標籤所在的位置插入新行:
<Param name="new_parameter" value="constant:true"/>
這是可能的還是要求太多並且手動編輯所有文件會更快?
答案1
這是一個使用xmlstarlet
XPath 的解決方案。我擴展了 XML 來示範我們可以挑選特定的節點:
解決方案
xmlstarlet edit \
--subnode '//Node[Name/text()="Mapper"]/Action' --type elem --name 'Param' \
--var nap '$prev' \
--insert '$nap' --type attr --name 'name' --value 'new_parameter' \
--insert '$nap' --type attr --name 'constant:true'
我們建立一個新的子節點,Node/Action
其中還有一個Name
具有文字值的元素Mapper
。我們將這個新節點分配給 XPath 變量,nap
以便我們可以輕鬆引用它。最後我們向其中插入兩個屬性。
XML 範例
<root>
<Node disablePersistence="true">
<Name>Mapper</Name>
<Action>
<Class-Name>com.test.component.Mapper</Class-Name>
<Param name="output_url" value="constant:file:///output.xml"/>
<Param name="xml_url" value="constant:file:///input.xml"/>
<Param name="xsl_url" value="constant:file:///template.xsl"/>
</Action>
<Next-Node>ComposeMessage</Next-Node>
</Node>
<Node disablePersistence="true">
<Name>DoNotTouchMe</Name>
<Action>
<Class-Name>com.test.component.Mapper</Class-Name>
<Param name="output_url" value="constant:file:///output.xml"/>
<Param name="xml_url" value="constant:file:///input.xml"/>
<Param name="xsl_url" value="constant:file:///template.xsl"/>
</Action>
<Next-Node>ComposeMessage</Next-Node>
</Node>
</root>
結果
<root>
<Node disablePersistence="true">
<Name>Mapper</Name>
<Action>
<Class-Name>com.test.component.Mapper</Class-Name>
<Param name="output_url" value="constant:file:///output.xml"/>
<Param name="xml_url" value="constant:file:///input.xml"/>
<Param name="xsl_url" value="constant:file:///template.xsl"/>
<Param name="new_parameter" constant:true=""/>
</Action>
<Next-Node>ComposeMessage</Next-Node>
</Node>
<Node disablePersistence="true">
<Name>DoNotTouchMe</Name>
<Action>
<Class-Name>com.test.component.Mapper</Class-Name>
<Param name="output_url" value="constant:file:///output.xml"/>
<Param name="xml_url" value="constant:file:///input.xml"/>
<Param name="xsl_url" value="constant:file:///template.xsl"/>
</Action>
<Next-Node>ComposeMessage</Next-Node>
</Node>
</root>