【问题标题】:Anonymizing the xml: how to remove data while leaving the tags in Java? [duplicate]匿名化 xml:如何在 Java 中保留标签的同时删除数据? [复制]
【发布时间】:2016-11-11 09:33:24
【问题描述】:

给定一个字符串类型的 xml 结构,我正在寻找一种方法来用四个星号替换数据,同时将标签留在原处。也就是从这个开始

<one> <two> abc </two> <two> def </two> </one>

我希望它变成

<one> <two> **** </two> <two> **** </two> </one>

我试过了

requestBody.replaceAll(">[^<]+?<","> **** <")

但我也捕获了两个相邻标签之间的任何空格,因此

<one> **** <two> **** </two> **** <two> **** </two> **** </one>

我怎样才能实现我的目标?有什么建议吗?

Here 进行一些测试。

编辑

按照 Michael Kay 的建议,我找到了这个解决方案

/**
 * Anonimyzes an xml structure replacing all data between tags with 4 asterisks. 
 * Tags won't be replaced.
 * 
 * @param xmlInput the string representing the xml to be anonymized
 * @return the anonymized xml structure.
 */
private String anonymizeXml(String xmlInput){
    String anonimizedXml=null;
    try {
        TransformerFactory factory = TransformerFactory.newInstance();
        Source xslt = new StreamSource(new StringReader("<xsl:transform version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:template match=\"*\">  <xsl:copy>   <xsl:apply-templates/>  </xsl:copy></xsl:template><xsl:template match=\"text()[normalize-space()]\"> **** </xsl:template></xsl:transform>"));
        Transformer transformer;
        transformer = factory.newTransformer(xslt);
        Source text = new StreamSource(new StringReader(xmlInput));
        
        StringWriter writer = new StringWriter();
        transformer.transform(text, new StreamResult(writer));
        anonimizedXml = writer.toString();
        
    } catch (TransformerConfigurationException e) {
        e.printStackTrace();
    } catch (TransformerException e) {
        e.printStackTrace();
    }
    return anonimizedXml;
}

【问题讨论】:

  • 您不应使用正则表达式解析 XML 或任何其他树状语法。或者换句话说,工作的错误工具。使用 XML 解析器来定位和替换所有文本节点。
  • @tucuxi 你能再具体一点吗?你有什么建议?

标签: java regex xml


【解决方案1】:

这是一个非常简单的 XSLT 转换的工作:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="*">
  <xsl:copy>
   <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:template match="text()[normalize-space()]">****</xsl:template>
</xsl:transform>

【讨论】:

    【解决方案2】:

    这个任务对于单个 RegExp 来说有点太重了。您可以使用一个正则表达式来查找包含标签的位置:

    Pattern pattern = Pattern.compile("<[a-z]>[^<]+?</[a-z]>");
    Matcher matcher = pattern.matcher(xmlString);
    while(matcher.find()) {
        System.out.println(xmlString.substring(matcher.start(), matcher.end());
    }
    

    将打印:

    <two> abc </two>
    <two> def </two>
    

    保存每个匹配的位置后,您可以使用原始正则表达式在子字符串中查找要替换的位置。添加到子字符串匹配位置的第一个匹配的开始位置将为您提供要在 xmlString 中替换的位置。

    当您拥有所有位置后,您可以开始替换部分 xmlString using substring。确保先替换最后一个匹配项,因为每次替换较早的零件时,后面零件的位置都会改变。

    【讨论】:

      猜你喜欢
      • 2010-10-08
      • 2016-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-28
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      相关资源
      最近更新 更多