【问题标题】:Java xpath to return an entire element as stringJava xpath以字符串形式返回整个元素
【发布时间】:2012-12-06 07:43:33
【问题描述】:

我需要使用 java xpath 通过 id 将 xml 元素作为字符串返回。

给定...

<svg>
    <g id="Background">
    </g>
    <g id="Outline">
        <polygon fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round"     stroke-miterlimit="10" points=" 119.813,57.875 119.188,57.87" />
    </g>
    <g id="Base_Colour" transform="matrix(0.25 0 0 0.25 0 0)">
        <path fill="#ADB1AF" d="M112.25,208l-8,20.25l-0.5-1.75l0.75-0.5v-1.5l0.75-0.5v-1.5L106,222v-1.5l0.75-0.5v-1.5l0.75-0.5v-1.5"/>
        <path fill="#625595" d="M112.25,208l5.25-14.5l30-30.25l2.25-1.5l41.5-20.5l49.75-9.5h4.25l49,3l48.75"/>
    </g>
</svg>

返回的值需要是...

<g id="Outline">
    <polygon fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round"     stroke-miterlimit="10" points=" 119.813,57.875 119.188,57.87" />
</g> 

我已经在 Google 上进行了广泛搜索,但我尝试过的任何方法都无法返回整个元素。需要 Xpath,因为我想通过 id 查询任何级别的 g 标签。

【问题讨论】:

标签: java xml xpath


【解决方案1】:

永远不会有 xpath 会返回包含 XML 语法的字符串。

【讨论】:

  • 数字基于我所遇到的。您是否有其他可以满足上述要求的解决方案的想法?
  • 使用 xpath 找到您关心的元素,然后使用通常的 Java API 将其序列化,以将 XML 序列化为字符串。
  • “没有 xpath”?措辞很严肃,有个实现,你可以在其中写/*/g[@id='Outline']/outer-xml(.)
  • @bmargulies,永远不要说“从不”:) w3.org/TR/xpath-functions-30/#func-serialize
  • @BeniBela,甚至还有一个标准 XPath 3.0 函数:w3.org/TR/xpath-functions-30/#func-serialize :)
【解决方案2】:

我不了解 Java,但在 .NET 世界中会使用

doc.DocumentElement.SelectSingleNode("/*/g[@id='Outline']").OuterXml

【讨论】:

  • 问题清楚地写着“java”,为什么还要在这里提到.Net
  • @lidermin,是的,而且问题清楚地说是“XPath”。除了“java”之外,这个问题还清楚地标有“xml”和“xpath”。这个答案是针对问题的 XPath/XML 方面的——涵盖了标记所指示的三个区域中的两个。作者明确表示:“需要 Xpath”。一个人可能知道 Java,但如果不了解 XPath,任何答案都将是不完整的。如果您理解这一点,我们将不胜感激。
  • @Dimitre_Novatatchev,好的,但是没有必要仅仅因为观察就在下面对我的答案投反对票,更重要的是考虑到我提供的解决方案甚至不是我的,我在那里发布了学分,它将是复制/粘贴给在 Java 世界中遇到类似情况的任何其他人
  • @lidermin,你为什么认为我对你的回答投了反对票?您能否问自己同样的问题,尤其是为什么 my 的答案在您的评论出现的同时被否决?我认为您的答案可能已被否决,因为它建议使用纯 Java 解决方案,但这不满足 OP 的要求,引用:“需要 Xpath”。我希望那些对你的答案和我的答案投反对票的人现在可以扭转他们的行为。
【解决方案3】:

我找到的解决方案是使用 xpath 获取 org.w3c.dom.Node(DOM 也可以)。然后我从节点创建了一个 javax.xml.transform.dom.DOMSource 并使用 javax.xml.transform.TransformerFactory 将其转换为字符串。

Node node = // the node you want to serialize
xmlOutput = new StreamResult(new StringWriter());
transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(node), xmlOutput);
String nodeAsAString = xmlOutput.getWriter().toString();

这很容易被分解成一个类以供重用。不幸的是,Java 中没有 .OuterXml 属性,而 .NET 中没有。现在所有 .NETer 都可以傻笑了。

【讨论】:

    【解决方案4】:

    我用这段代码解决了我的问题:

    public static String getOuterXml(Node node)
        throws TransformerConfigurationException, TransformerException {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty("omit-xml-declaration", "yes");
    
        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(node), new StreamResult(writer));
        return writer.toString();         
    }
    

    致谢:chick.Net

    【讨论】:

      【解决方案5】:

      有时您必须在没有 Java 中的 xml 文档的情况下执行此操作;我发现下面的代码非常完整

      import java.io.IOException;
      import java.io.StringReader;
      
      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;
      import javax.xml.parsers.ParserConfigurationException;
      import javax.xml.xpath.XPath;
      import javax.xml.xpath.XPathConstants;
      import javax.xml.xpath.XPathExpression;
      import javax.xml.xpath.XPathExpressionException;
      import javax.xml.xpath.XPathFactory;
      
      import org.w3c.dom.Document;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      import org.xml.sax.InputSource;
      import org.xml.sax.SAXException;
      
      String responseMsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><YourMessage><MyTag>MyTagValue</MyTag></YourMessage>";
      String expressionToExract = "/YourMessage/MyTag";
      String xmlNodeWithData = xpathTester.getXmlNode(responseMsg, expressionToExract);
      //above xmlNodeWithData will have this value '<MyTag>MyTagValue</MyTag>'
      
      private String getXmlNode(String resultMsg, String expression)
              throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
          String xmlNodeWithData="";
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          DocumentBuilder builder = factory.newDocumentBuilder();
          InputSource is = null;
          StringReader sr = null;
          sr = new StringReader(resultMsg);
          is = new InputSource(sr);
      
          Document doc = builder.parse(is);
          XPathFactory xPathfactory = XPathFactory.newInstance();
          XPath xpath = xPathfactory.newXPath();
          XPathExpression expr = xpath.compile(expression);
      
          Node node = (Node)expr.evaluate(doc, XPathConstants.NODE);      
          xmlNodeWithData += "<" + node.getNodeName() + ">";
          NodeList nodeList = node.getChildNodes();
      
          for (int nodeIndex=0; nodeIndex < nodeList.getLength(); nodeIndex++) {
              Node nodeChild = nodeList.item(nodeIndex);          
              if (nodeChild.getNodeName().contains("#text")) {
                  xmlNodeWithData += nodeChild.getTextContent();
                  continue;
              }
              xmlNodeWithData += "<" + nodeChild.getNodeName() + ">";         
              xmlNodeWithData += nodeChild.getTextContent();
              xmlNodeWithData += "</" + nodeChild.getNodeName() + ">";
          }
          xmlNodeWithData += "</" + node.getNodeName() + ">";
          if (sr != null) {
              sr.close();
          }
          return xmlNodeWithData;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-04-26
        • 2014-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多