Мне нужна помощь в создании выражения xpath для чтения всех имен узлов, значений узлов и атрибутов в строке xml. Я сделал это:Java, XPath Expression для чтения всех имен узлов, значений узлов и атрибутов
private List<String> listOne = new ArrayList<String>();
private List<String> listTwo = new ArrayList<String>();
public void read(String xml) {
try {
// Turn String into a Document
Document document = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes()));
// Setup XPath to retrieve all tags and values
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xPath.evaluate("//text()[normalize-space()='']", document, XPathConstants.NODESET);
// Iterate through nodes
for(int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
listOne.add(node.getNodeName());
listTwo.add(node.getNodeValue());
// Another list to hold attributes
}
} catch(Exception e) {
LogHandle.info(e.getMessage());
}
}
Я нашел выражение //text()[normalize-space()='']
онлайн; однако это не сработает. Когда я пытаюсь получить имя узла от listOne
, это всего лишь #text
. Я пробовал //
, но это тоже не работает. Если у меня был этот XML:
<Data xmlns="Somenamespace.nsc">
<Test>blah</Test>
<Foo>bar</Foo>
<Date id="2">12242016</Date>
<Phone>
<Home>5555555555</Home>
<Mobile>5555556789</Mobile>
</Phone>
</Data>
listOne[0]
должен держать Data
, listOne[1]
должен держать Test
, listTwo[1]
blah
должны держать, и т.д ... Все атрибуты будут сохранены в другом параллельном списке.
Какое выражение должно быть xPath
оценить?
Примечание: XML-строка может иметь разные теги, поэтому я не могу ничего жестко кодировать.
Update: Пробовал этот цикл:
NodeList nodeList = (NodeList) xPath.evaluate("//*", document, XPathConstants.NODESET);
// Iterate through nodes
for(int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
listOne.add(i, node.getNodeName());
// If null then must be text node
if(node.getChildNodes() == null)
listTwo.add(i, node.getTextContent());
}
Однако, это только получает корневой элемент Data
, то просто останавливается.
'текст()' относится к содержимому элемента. В вашем примере XML, 'blah',' bar' и '12242016' являются текстовыми узлами. Итак, 'text()' вероятно, не то, что вы хотите. – VGR
Спасибо! Если 'text()' дает содержимое элемента, будет ли 'node()' давать узлы? – syy
Я думаю, что может понадобиться некоторое разъяснение. В XML «узел» относится к любой возможной части информации в XML-документе, включая текст, комментарии, инструкции по обработке и т. Д., Тогда как «элемент» относится к информации, состоящей из начального тега и соответствующего конечного тега, или одиночный самозакрывающийся тег (' '). Вы действительно хотите прочитать каждый узел, или только каждый элемент и его атрибуты? –
VGR