当前位置: 首页 > 知识库问答 >
问题:

在Java中从XML中删除重复的命名空间

萧琛
2023-03-14

我有以下肥皂反应作为示例:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:mycompany:Service:2" xmlns:urn1="urn:mycompany:Customer:2">
  <soapenv:Header />
  <soapenv:Body>
    <urn:GetResponse>
      <urn:StatusCode>002</urn:StatusCode>
      <urn:StatusMessage>Pass</urn:StatusMessage>
      <urn:CustomerAffiliations>
        <urn:CustomerAffiliation>
          <urn:CustomerID>II39642</urn:CustomerID>
          <urn:CustomerContactDetails>
            <ns3:Channel xmlns:ns3="urn:mycompany:Customer:2">Business Phone</ns3:Channel>
            <ns3:Value xmlns:ns3="urn:mycompany:Customer:2">5553647</ns3:Value>
          </urn:CustomerContactDetails>
        </urn:CustomerAffiliation>
      </urn:CustomerAffiliations>
    </urn:GetResponse>
  </soapenv:Body>
</soapenv:Envelope>

在soapenv:Envelope中,urn:mycompany:Customer:2已包含为urn1,但在ns3:Channel和ns3:Value中重复。

要求是清理xml内容,以便在子元素中使用soapenv:Envelope中声明的正确名称空间。

Java有没有办法清理/规范化这个xml内容并使用正确的命名空间使用和重复删除?

共有1个答案

齐锐进
2023-03-14

以下代码将仅对元素使用其继承版本替换“重复”命名空间(属性也可以有自己的命名空间)......

请注意,这具有一些可怕的时间复杂度,因此对于较大的XML文档,这可能会严重退化......所以不要在深度嵌套或大于几百个元素的文档上使用它...在某个时候,时间复杂度会咬你。

另一方面,对于像您的SOAP示例这样的小数据包,这就足够了。。。

private static final Namespace findFirst(List<Namespace> namespaces, String uri) {
    for (Namespace ns : namespaces) {
        if (ns.getURI().equals(uri)) {
            return ns;
        }
    }
    return null;
}


public static final void dedupElementNamespaces(Element node) {
    List<Namespace> created = node.getNamespacesIntroduced();
    if (!created.isEmpty()) {
        // check anything new against other stuff...
        List<Namespace> inherited = node.getNamespacesInherited();
        // check out element against previous declarations....
        if (node.getNamespace().getPrefix() != "") {
            // never swap defaulted namespaces to anything with a prefix.
            Namespace ens = node.getNamespace();
            Namespace use = findFirst(inherited, node.getNamespaceURI());
            if (use != null && use != ens) {
                node.setNamespace(use);
            }
        }           

    }
    for (Element e : node.getChildren()) {
        dedupElementNamespaces(e);
    }
}

你可以用以下方式调用:

dedupElementNamespaces(doc.getRootElement());

方法<代码>节点。getNamespacesIntroduced()和节点。getNamespacesInherited()通过扫描XML层次结构动态计算列表。。。因此,它们的性能取决于嵌套的深度。看见https://github.com/hunterhacker/jdom/blob/master/core/src/java/org/jdom2/Element.java#L1753

 类似资料:
  • 我有一个具有重复值的地图: 我想在地图上有 你知道如何去掉重复的值吗? 目前,我收到'java.util.ConcurrentModificationException'错误。 谢谢。

  • 我使用CXF从WSDL/XSD生成java类,然后返回XML(用于JMS)。 在生成的一个类中,它表示:

  • 问题内容: 尝试从Sybase到Microsoft SQL进行OPENQUERY时,我遇到错误: 通过OPENQUERY和OPENROWSET获得的结果集中不允许重复的列名。列名称“ PatientID”是重复的。 我建立的查询基于相似的entryID和PatientID联接了2个表。 例如: 当然,真正的查询不仅包含更多信息。 是否有重命名或删除AdmID和PatID列之一的好方法? 我尝试过:

  • 我有一个列名称为空的dataframe: 我如何删除空列名而不考虑位置?

  • 所以,我有两个多维数组。 数组值示例: 这就是我想要的 我想从组合中获得所有唯一的数组,并用它填充唯一的组合。 我尝试了这个函数,但它只填充了5个数组,真奇怪!

  • 这段代码运行良好,但我想知道它的性能,我指的是它的总体时间复杂度?