プログラムはXPath式を使用してXMLファイルから読み取ることが許可されている必要があります。 すでにJDOM2を使用してプロジェクトを開始しましたが、別のAPIに切り替えることは望ましくありません。 難易度は、要素または属性を読み取る必要があるかどうかをプログラムが事前に知っていないことです。 APIは、XPath式を与えるだけでコンテンツ(文字列)を受け取る関数を提供していますか? JDOM2のXPathについて知っているところから、さまざまな型のオブジェクトを使用して、属性または要素を指すXPath式を評価します。 私はXPath式が指し示す属性/要素の内容のみに興味があります。ここでJava XML JDOM2 XPath - XPath式を使用してXML属性および要素からテキスト値を読み取る
は、例えばXMLファイルです:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
これは以下のように私のプログラムが見えるものです:もう一つの考えはに、XPath式に「@」文字を検索することです
package exampleprojectgroup;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
public class ElementAttribute2String
{
ElementAttribute2String()
{
run();
}
public void run()
{
final String PATH_TO_FILE = "c:\\readme.xml";
/* It is essential that the program has to work with a variable amount of XPath expressions. */
LinkedList<String> xPathExpressions = new LinkedList<>();
/* Simulate user input.
* First XPath expression points to attribute,
* second one points to element.
* Many more expressions follow in a real situation.
*/
xPathExpressions.add("/bookstore/book/@category");
xPathExpressions.add("/bookstore/book/price");
/* One list should be sufficient to store the result. */
List<Element> elementsResult = null;
List<Attribute> attributesResult = null;
List<Object> objectsResult = null;
try
{
SAXBuilder saxBuilder = new SAXBuilder(XMLReaders.NONVALIDATING);
Document document = saxBuilder.build(PATH_TO_FILE);
XPathFactory xPathFactory = XPathFactory.instance();
int i = 0;
for (String string : xPathExpressions)
{
/* Works only for elements, uncomment to give it a try. */
// XPathExpression<Element> xPathToElement = xPathFactory.compile(xPathExpressions.get(i), Filters.element());
// elementsResult = xPathToElement.evaluate(document);
// for (Element element : elementsResult)
// {
// System.out.println("Content of " + string + ": " + element.getText());
// }
/* Works only for attributes, uncomment to give it a try. */
// XPathExpression<Attribute> xPathToAttribute = xPathFactory.compile(xPathExpressions.get(i), Filters.attribute());
// attributesResult = xPathToAttribute.evaluate(document);
// for (Attribute attribute : attributesResult)
// {
// System.out.println("Content of " + string + ": " + attribute.getValue());
// }
/* I want to receive the content of the XPath expression as a string
* without having to know if it is an attribute or element beforehand.
*/
XPathExpression<Object> xPathExpression = xPathFactory.compile(xPathExpressions.get(i));
objectsResult = xPathExpression.evaluate(document);
for (Object object : objectsResult)
{
if (object instanceof Attribute)
{
System.out.println("Content of " + string + ": " + ((Attribute)object).getValue());
}
else if (object instanceof Element)
{
System.out.println("Content of " + string + ": " + ((Element)object).getText());
}
}
i++;
}
}
catch (IOException ioException)
{
ioException.printStackTrace();
}
catch (JDOMException jdomException)
{
jdomException.printStackTrace();
}
}
}
それが属性または要素を指しているかどうかを判断する。 これは私に望ましい結果をもたらしますが、私はより洗練された解決策があることを望みます。 JDOM2 APIはこの問題に役立つものは何ですか? 要件を満たすためにコードを再設計できますか?
ありがとうございます!
JDOM2の 'Attribute'は' Content'のサブクラスですか? http://www.jdom.org/docs/apidocs/org/jdom2/Attribute.htmlには表示されていないので、私の答えが「XPathExpression xPathExpression = xPathFactory.compile(xPathExpressions.get(i) )、Filters.content()) 'は要素と属性を扱います。 –
ああ...うんざり。私は属性が内容ではないことを忘れていました。それは 'getValue()'メソッドを持ち、私は仮定しました。これについて少し考えてみましょう。 – rolfl
私は、曖昧なXPath結果を検査する以外にも、より良いやり方を考えることはできません。 ElementノードとAttributeノードの両方が共通の祖先を共有している場合、JDOMはやや簡単に作業を進めることができましたが、それが実現不可能な理由は他にもあります。私はOPで記述された基本的なメカニズムを変更するのではなく、コードを整理するために関数抽出を推奨する答えを編集しました。 – rolfl