gpt4 book ai didi

java - 有没有一种方法可以通过每个节点可用的行号通过 SAX/DOM 解析 XML

转载 作者:数据小太阳 更新时间:2023-10-29 01:53:57 25 4
gpt4 key购买 nike

我已经为大型 XML 文档格式编写了一个 DOM 解析器,其中包含许多可用于自动生成 Java 代码的项目。这仅限于随后合并到动态生成的 Java 源文件中的小表达式。

到目前为止 - 非常好。一切正常。

但是 - 我希望能够嵌入包含 Java 代码的 XML 节点的行号(这样如果配置包含不可编译的代码,每个方法都会有一个指向源 XML 文档的指针和行便于调试的编号)。我在解析时不需要行号,也不需要验证 XML 源文档并在特定行号处抛出错误。我需要能够访问我的 DOM 或每个 SAX 事件中每个节点和属性的行号。

关于我如何能够实现这一点有什么建议吗?

附言另外,我读到 StAX 有一种在解析时获取行号的方法,但理想情况下,我希望在 Java 4/5 中通过常规 SAX/DOM 处理获得相同的结果,而不是成为 Java 6+ 应用程序或承担额外的 . jar文件。

最佳答案

我知道这个线程有点旧(抱歉),但我花了很长时间才破解这个难题,我不得不与某人分享解决方案......

您似乎只能使用不构建 DOM 的 SAX 获取行号。 DOM 解析器不提供行号,也不会让您靠近它正在使用的 SAX 解析器。我的解决方案是使用 SAX 源和 DOM 结果进行空的 XSLT 转换,但即便如此,还是有人竭尽全力隐藏了这一点。请参阅下面的代码。

我将位置信息作为属性添加到每个元素,并使用我自己的命名空间,这样我就可以使用 XPath 查找元素并报告数据的来源。

希望对您有所帮助:

// The file to parse.
String systemId = "myxml.xml";

/*
* Create transformer SAX source that adds current element position to
* the element as attributes.
*/
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
LocationFilter locationFilter = new LocationFilter(xmlReader);

InputSource inputSource = new InputSource(new FileReader(systemId));
// Do this so that XPath function document() can take relative URI.
inputSource.setSystemId(systemId);
SAXSource saxSource = new SAXSource(locationFilter, inputSource);

/*
* Perform an empty transformation from SAX source to DOM result.
*/
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMResult domResult = new DOMResult();
transformer.transform(saxSource, domResult);
Node root = domResult.getNode();

...
class LocationFilter extends XMLFilterImpl {

LocationFilter(XMLReader xmlReader) {
super(xmlReader);
}

private Locator locator = null;

@Override
public void setDocumentLocator(Locator locator) {
super.setDocumentLocator(locator);
this.locator = locator;
}

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

// Add extra attribute to elements to hold location
String location = locator.getSystemId() + ':' + locator.getLineNumber() + ':' + locator.getColumnNumber();
Attributes2Impl attrs = new Attributes2Impl(attributes);
attrs.addAttribute("http://myNamespace", "location", "myns:location", "CDATA", location);
super.startElement(uri, localName, qName, attrs);
}
}

关于java - 有没有一种方法可以通过每个节点可用的行号通过 SAX/DOM 解析 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2798376/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com