代码之家  ›  专栏  ›  技术社区  ›  svrist

在XML文档中插入/替换XML标记

  •  3
  • svrist  · 技术社区  · 17 年前

    我有一个 XmlDocument 在Java中,用 Weblogic XmlDocument 语法分析器。

    我想替换这个标签的内容 XMLDocument 使用我自己的数据,或者如果标签不在,则插入它。

    <customdata>
       <tag1 />
       <tag2>mfkdslmlfkm</tag2>
       <location />
       <tag3 />
    </customdata>
    

    例如,我想在位置标记中插入一些URL:

    <location>http://something</location>
    

    但是,否则就让XML保持原样。

    当前我使用 XMLCursor :

        XmlObject xmlobj = XmlObject.Factory.parse(a.getCustomData(), options);
        XmlCursor xmlcur = xmlobj.newCursor();
    
        while (xmlcur.hasNextToken()) {
          boolean found = false;
          if (xmlcur.isStart() && "schema-location".equals(xmlcur.getName().toString())) {
            xmlcur.setTextValue("http://replaced");
            System.out.println("replaced");
            found = true;
          } else if (xmlcur.isStart() && "customdata".equals(xmlcur.getName().toString())) {
            xmlcur.push();
          } else if (xmlcur.isEnddoc()) {
            if (!found) {
              xmlcur.pop();
              xmlcur.toEndToken();
              xmlcur.insertElementWithText("schema-location", "http://inserted");
              System.out.println("inserted");
            }
    
          }
          xmlcur.toNextToken();
        }
    

    我想找个“快点” xquery 自从 XML文档 有一个 execQuery 方法,但并不容易。

    有人有比这更好的方法吗?看起来有点复杂。

    4 回复  |  直到 9 年前
        1
  •  4
  •   Cheekysoft Moz Morris    17 年前

    基于XPath的方法怎么样?我喜欢这种方法,因为它的逻辑非常容易理解。代码基本上是自记录的。

    如果XML文档作为org.w3c.dom.document对象(大多数解析器都会返回)提供给您,那么您可以执行以下操作:

    // get the list of customdata nodes
    NodeList customDataNodeSet = findNodes(document, "//customdata" );
    
    for (int i=0 ; i < customDataNodeSet.getLength() ; i++) {
      Node customDataNode = customDataNodeSet.item( i );
    
      // get the location nodes (if any) within this one customdata node
      NodeList locationNodeSet = findNodes(customDataNode, "location" );
    
      if (locationNodeSet.getLength() > 0) {
        // replace
        locationNodeSet.item( 0 ).setTextContent( "http://stackoverflow.com/" );
      }
      else {
        // insert
        Element newLocationNode = document.createElement( "location" );
        newLocationNode.setTextContent("http://stackoverflow.com/" );
        customDataNode.appendChild( newLocationNode );
      }
    }
    

    下面是帮助器方法findnodes,它执行xpath搜索。

    private NodeList findNodes( Object obj, String xPathString )
      throws XPathExpressionException {
    
      XPath xPath = XPathFactory.newInstance().newXPath();
      XPathExpression expression = xPath.compile( xPathString );
      return (NodeList) expression.evaluate( obj, XPathConstants.NODESET );
    }
    
        2
  •  1
  •   Olly    17 年前

    面向对象的方法怎么样?您可以将XML反序列化为对象,在对象上设置位置值,然后序列化回XML。

    XStream 这真的很容易。

    例如,您将定义主对象,在您的例子中是customdata(我使用公共字段保持示例的简单性):

    public class CustomData {
      public String tag1;
      public String tag2;
      public String location;
      public String tag3;
    }
    

    然后初始化xstream:

    XStream xstream = new XStream();
    // if you need to output the main tag in lowercase, use the following line
    xstream.alias("customdata", CustomData.class);  
    

    现在,您可以从XML构造一个对象,在该对象上设置位置字段并重新生成XML:

    CustomData d = (CustomData)xstream.fromXML(xml);
    d.location = "http://stackoverflow.com";
    xml = xstream.toXML(d);
    

    听起来怎么样?

        3
  •  1
  •   NoNaMe    13 年前

    如果您不知道该模式,那么Xstream解决方案可能不是解决方案。至少Xstream现在在你的雷达上,将来可能会派上用场!

        4
  •  0
  •   Sujania Wayne Ye    10 年前

    你应该可以这样做 query

    尝试

     fn:replace(string,pattern,replace)
    

    我是XQuery的新手,我发现使用XQuery是一种痛苦的查询语言,但是一旦你通过了最初的学习曲线,它就会很好地工作。

    我还是希望有一种更简单的方法,同样有效?

    推荐文章