替换 XML 元素的值?sed正则表达式? [英] Replace an XML element's value? Sed regular expression?

查看:48
本文介绍了替换 XML 元素的值?sed正则表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获取一个 XML 文件并替换元素的值.例如,如果我的 XML 文件如下所示:

I want to take an XML file and replace an element's value. For example if my XML file looks like this:

<abc>
    <xyz>original</xyz>
</abc>

我想用另一个字符串替换 xyz 元素的原始值,不管它是什么,这样生成的文件看起来像这样:

I want to replace the xyz element's original value, whatever it may be, with another string so that the resulting file looks like this:

<abc>
    <xyz>replacement</xyz>
</abc>

你会怎么做?我知道我可以编写一个 Java 程序来执行此操作,但我认为这对于替换单个元素的值来说太过分了,并且可以使用 sed 使用正则表达式轻松完成替换.然而,我对这个命令还不是新手,我希望有一些善良的灵魂阅读这篇文章能够为我提供正确的正则表达式来完成这项工作.

How would you do this? I know I could write a Java program to do this but I assume that that's overkill for replacing a single element's value and that this could be easily done using sed to do a substitution using a regular expression. However I'm less than novice with that command and I'm hoping some kind soul reading this will be able to spoon feed me the correct regular expression for the job.

一个想法是做这样的事情:

One idea is to do something like this:

sed s/\<xyz\>.*\<\\xyz\>/\<xyz\>replacement\<\\xyz\>/ <original.xml >new.xml

也许我最好用我想要的内容替换文件的整行,因为我会知道元素名称和我想要使用的新值?但这假设有问题的元素在一行上,并且没有其他 XML 数据在同一行上.我宁愿有一个命令,它基本上会用我指定的新字符串替换元素 xyz 的值,而不必担心元素是否都在一行上,等等.

Maybe it's better for me to just replace the entire line of the file with what I want it to be, since I will know the element name and the new value I want to use? But this assumes that the element in question is on a single line and that no other XML data is on the same line. I'd rather have a command which will basically replace element xyz's value with a new string that I specify and not have to worry if the element is all on one line or not, etc.

如果 sed 不是这项工作的最佳工具,那么请联系我寻求更好的方法.

If sed is not the best tool for this job then please dial me in to a better approach.

如果有人能引导我朝着正确的方向前进,我将非常感激,您可能会为我节省数小时的反复试验.提前致谢!

If anyone can steer me in the right direction I'll really appreciate it, you'll probably save me hours of trial and error. Thanks in advance!

--詹姆斯

推荐答案

好的,所以我咬紧牙关,花时间编写了一个 Java 程序,它可以满足我的需求.下面是我的 main() 方法调用的操作方法,它可以完成这项工作,以防将来对其他人有帮助:

OK so I bit the bullet and took the time to write a Java program which does what I want. Below is the operative method called by my main() method which does the work, in case this will be helpful to someone else in the future:

/**
 * Takes an input XML file, replaces the text value of the node specified by an XPath parameter, and writes a new
 * XML file with the updated data.
 * 
 * @param inputXmlFilePathName
 * @param outputXmlFilePathName
 * @param elementXpath
 * @param elementValue
 * @param replaceAllFoundElements
 */
public static void replaceElementValue(final String inputXmlFilePathName,
                                       final String outputXmlFilePathName,
                                       final String elementXpathExpression,
                                       final String elementValue,
                                       final boolean replaceAllFoundElements)
{
    try
    {
        // get the template XML as a W3C Document Object Model which we can later write back as a file
        InputSource inputSource = new InputSource(new FileInputStream(inputXmlFilePathName));
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        Document document = documentBuilderFactory.newDocumentBuilder().parse(inputSource);

        // create an XPath expression to access the element's node
        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();
        XPathExpression xpathExpression = xpath.compile(elementXpathExpression);

        // get the node(s) which corresponds to the XPath expression and replace the value
        Object xpathExpressionResult = xpathExpression.evaluate(document, XPathConstants.NODESET);
        if (xpathExpressionResult == null)
        {
            throw new RuntimeException("Failed to find a node corresponding to the provided XPath.");
        }
        NodeList nodeList = (NodeList) xpathExpressionResult;
        if ((nodeList.getLength() > 1) && !replaceAllFoundElements)
        {
            throw new RuntimeException("Found multiple nodes corresponding to the provided XPath and multiple replacements not specified.");
        }
        for (int i = 0; i < nodeList.getLength(); i++)
        {
            nodeList.item(i).setTextContent(elementValue);
        }

        // prepare the DOM document for writing
        Source source = new DOMSource(document);

        // prepare the output file
        File file = new File(outputXmlFilePathName);
        Result result = new StreamResult(file);

        // write the DOM document to the file
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(source, result);
    }
    catch (Exception ex)
    {
        throw new RuntimeException("Failed to replace the element value.", ex);
    }
}

我像这样运行程序:

$ java -cp xmlutility.jar com.abc.util.XmlUtility input.xml output.xml '//name/text()' JAMES

这篇关于替换 XML 元素的值?sed正则表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆