【问题标题】:Trying to use .replace() to replace XML dependencies extracted by using XPATH java尝试使用 .replace() 替换使用 XPATH java 提取的 XML 依赖项
【发布时间】:2021-07-25 10:13:42
【问题描述】:

我有一个 pom xml 和 pom-web xml。 我试图通过使用 Xpath 将依赖项提取到变量中并尝试使用变量在 pom.xml 文件中执行 .replace 来将依赖项从 pom-web 复制到 pom.xml。但我无法通过变量替换内容,因为 .contains() 的 if 条件为 false。下面的任何帮助都是我使用的代码

pom.xml

<project>
    <dependencies>
        <dependency>
            <groupId>com.test.tm</groupId>
            <artifactId>gameJdk</artifactId>
            <version>1.0.0.1</version>
        </dependency>
        <!-- For Compress JS -->
        <dependency>
            <groupId>com.yahoo.platform.yui</groupId>
            <artifactId>yuicompressor</artifactId>
            <version>2.4.7</version>
        </dependency>
        <dependency>
            <groupId>com.sybase</groupId>
            <artifactId>EccpressoFIPSJca</artifactId>
            <version>7.0</version>
        </dependency>

        <dependency>
            <groupId>com.sybase</groupId>
            <artifactId>EccpressoFIPS</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.12.0</version>
        </dependency>
    </dependencies>
</project>

pom-web.xml

<project>
    <dependencies>
        <dependency>
            <groupId>com</groupId>
            <artifactId>passwordsdk</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!-- For Compress JS -->
        <dependency>
            <groupId>com.yahoo.platform.yui</groupId>
            <artifactId>yuicompressor</artifactId>
            <version>2.4.7</version>
        </dependency>
        <dependency>
            <groupId>com.sybase</groupId>
            <artifactId>EccpressoFIPSJca</artifactId>
            <version>7.0</version>
        </dependency>

        <dependency>
            <groupId>com.data</groupId>
            <artifactId>EccpressoFIPS</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>tesdt</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.12.0</version>
        </dependency>
    </dependencies>
</project>

替换后的预期 pom.xml 输出:

<project>
    <dependencies>
        <dependency>
            <groupId>com</groupId>
            <artifactId>passwordsdk</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!-- For Compress JS -->
        <dependency>
            <groupId>com.yahoo.platform.yui</groupId>
            <artifactId>yuicompressor</artifactId>
            <version>2.4.7</version>
        </dependency>
        <dependency>
            <groupId>com.sybase</groupId>
            <artifactId>EccpressoFIPSJca</artifactId>
            <version>7.0</version>
        </dependency>

        <dependency>
            <groupId>com.data</groupId>
            <artifactId>EccpressoFIPS</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>tesdt</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.12.0</version>
        </dependency>
    </dependencies>
</project>

我使用 xpath 提取依赖关系的代码

import java.io.StringWriter;
import java.nio.file.Files;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.slf4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public static void main (String args[]){
        





 Path c1=Paths.get(prop.getProperty("testPom"));
            Path c2=Paths.get(prop.getProperty("testPomweb"));
            //String pom = readFile(CfoServerModifications.class.getResourceAsStream(prop.getProperty("testPom")));
            //String web = readFile(CfoServerModifications.class.getResourceAsStream(prop.getProperty("testPomweb")));            
            String pomFile = new String(Files.readAllBytes(c1),StandardCharsets.UTF_8);
            String pomWeb = new String(Files.readAllBytes(c2),StandardCharsets.UTF_8);
            Document doc_web = Jsoup.parse(pomWeb,"",Parser.xmlParser());
            Document doc_pom = Jsoup.parse(pomFile,"",Parser.xmlParser());
            doc_pom.outputSettings().prettyPrint(false);
            doc_web.outputSettings().prettyPrint(false);
           // System.out.println(doc_pom.outputSettings().prettyPrint(false));
            Elements dependencies_web = doc_web.select("project>dependencies");
            Elements dependencies_pom = doc_pom.select("project>dependencies");
            //log.info(dependencies_web.toString());
            // remove the old dependencies
            dependencies_pom.clear();
            //log.info("pom clear"+dependencies_pom.toString());
            //add the new dependencies
            dependencies_pom.addAll(dependencies_web);
            //log.info("pom web added to pom "+dependencies_pom.toString());
           
            Files.write(Paths.get(prop.getProperty("dummyfile")),doc_pom.toString().getBytes());

【问题讨论】:

  • @firephil 我已经用你要求的内容更新了代码......我不确定上面是否回答了我的问题,我正在尝试使用 contains 替换现有节点并将 .replace 替换为新节点预期结果中列出的文件
  • 可能需要更多的导入,但是当您将鼠标悬停在它们上面时应该能够快速修复
  • 不要尝试使用正则表达式处理词法(序列化)XML:进行 XSLT 转换。
  • @Michael Kay 你能提供上述问题的代码答案吗?我觉得你正试图摆脱原来的问题
  • 我被这个问题困扰了一个星期,我很想今天解决这个问题,请帮助我达到预期的结果

标签: java xpath replace xml-parsing contains


【解决方案1】:

我推荐你使用Jsoup,它可以轻松解析xml,而不是重新发明轮子。

将每个 xml 文件读入内存,从一个 xml 复制依赖节点并用另一个替换它们。

这是一个工作示例:

package replacexmlnode;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;


public class ReplaceXmlNode {
    
  public static void main(String[] args) throws IOException {
    
    String pom = readFile(ReplaceNode.class.getResourceAsStream("pom-plain.xml"));
    String web = readFile(ReplaceNode.class.getResourceAsStream("pom-web.xml"));
    
    Document doc_web = Jsoup.parse(web,"",Parser.xmlParser());
    Document doc_pom = Jsoup.parse(pom,"",Parser.xmlParser());
    
    Elements dependencies_web = doc_web.select("project>dependencies");

    //remove old dependencies        
    doc_pom.select("project>dependencies").remove();

    // add new dependencies
    doc_pom.select("project").first().appendChild(dependencies_web.first());       
    
    doc_pom.outputSettings().prettyPrint(false);
    Files.write(Paths.get("pom-plain_out.xml"), doc_pom.toString().getBytes());
 }

  public static String readFile(InputStream in) throws IOException{
   
    return new String(in.readAllBytes(), StandardCharsets.UTF_8);
 }
}

如果你使用 maven 从 maven central

获取 Jsoup 依赖

【讨论】:

  • 这个 ddoesnt 工作,因为你通过标签获取这些元素,它正在使用不需要的 depeencies 标签......这就是为什么我使用 xpath 来获取项目级别下的特定依赖标签......使用上面的代码获取 xml 中的所有依赖标签,这不是我想要的
  • 如果你看这个stackoverflow.com/questions/67355118/… 这是它获取多个依赖标签的问题..当我想要特定的依赖标签时
  • 看到我仍然得到这样的输出 p6spy 3.7.0 这是逐行分割的......无论如何你可以在一行中使它像1.3这样吗?现在所有元素都被逐行分割,这弄乱了我现有的 xml 文档
  • 检查问题我已经把 Jsoup 输出给你看
  • 一个问题你可以在你的答案中更新这个,因为它可供所有人看到我在打印 org.jsoup.nodes.Document$OutputSettings@2437c6dc 时看到这个 --> System.out.println( doc_pom.outputSettings().prettyPrint(false));
猜你喜欢
  • 1970-01-01
  • 2016-07-05
  • 2021-07-25
  • 1970-01-01
  • 2016-01-13
  • 2013-10-12
  • 2021-01-18
  • 2019-03-05
  • 1970-01-01
相关资源
最近更新 更多