我正在使用 Xpath 和 Java。
XML 有大量的OBJECT_TYPES
,并且每个对象类型都有属性和参数。
每个属性和参数都有元素。
如何从 XML 文件执行以下操作。 我想知道如何使用 XPATH 字符串表达式选择所有属性元素,具体取决于 OBJECT_TYPE 字符串的名称。对象类型字符串名称取决于用户从列表中选择的名称。
我怎样才能做到这一点?
应该是这样的:
String expression = "/getObjType()/prop/*";
但是 getObjectType
是一种方法,因此我无法在字符串表达式中使用它。
XML 看起来像这样:
<type>
<OBJECT_TYPE>SiteData</OBJECT_TYPE>
<prop>
<DESCRIPTION>Site parameters</DESCRIPTION>
<PARENT>NULL</PARENT>
<VIRTUAL>0</VIRTUAL>
<VISIBLE>1</VISIBLE>
<PICTURE>NULL</PICTURE>
<HELP>10008</HELP>
<MIN_NO>1</MIN_NO>
<MAX_NO>1</MAX_NO>
<NAME_FORMAT>NULL</NAME_FORMAT>
</prop>
<param>
<PARAMETER>blabla</PARAMETER>
<DATA_TYPE>INTEGER</DATA_TYPE>
<DESCRIPTION>blaba</DESCRIPTION>
<MIN_NO>1</MIN_NO>
<MAX_NO>1</MAX_NO>
<ORDER1>1</ORDER1>
<NESTED>0</NESTED>
<DEFAULT1>NULL</DEFAULT1>
<FORMAT>0:16382</FORMAT>
</param>
<OBJECT_TYPE>Data</OBJECT_TYPE>
<prop>
<DESCRIPTION>Site parameters</DESCRIPTION>
<PARENT>NULL</PARENT>
<VIRTUAL>0</VIRTUAL>
<VISIBLE>1</VISIBLE>
<PICTURE>NULL</PICTURE>
<HELP>10008</HELP>
<MIN_NO>1</MIN_NO>
<MAX_NO>1</MAX_NO>
<NAME_FORMAT>NULL</NAME_FORMAT>
</prop>
<param>
<PARAMETER>gmgm</PARAMETER>
<DATA_TYPE>INTEGER</DATA_TYPE>
<DESCRIPTION>babla</DESCRIPTION>
<MIN_NO>1</MIN_NO>
<MAX_NO>1</MAX_NO>
<ORDER1>1</ORDER1>
<NESTED>0</NESTED>
<DEFAULT1>NULL</DEFAULT1>
<FORMAT>0:16382</FORMAT>
</param>
</type>
因此,根据 Object_type 的名称,我想要获取这些属性,并且我列出了 122 个对象类型,因此我必须使用一个变量来选择用户选择的类型。
public class PropXMLParsing {
static PropXMLParsing instance = null;
private List<String> list = new ArrayList<String>();
ObjType obj = new ObjType();
public static PropXMLParsing getInstance() {
if (instance == null) {
instance = new PropXMLParsing();
try {
instance.ParserForObjectTypes();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
return instance;
}
public void ParserForObjectTypes() throws SAXException, IOException,
ParserConfigurationException {
try {
FileInputStream file = new FileInputStream(new File(
"xmlFiles/CoreDatamodel.xml"));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory
.newInstance();
builderFactory.setNamespaceAware(true);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xp = XPathFactory.newInstance().newXPath();
final Map<String, Object> vars = new HashMap<String, Object>();
xp.setXPathVariableResolver(new XPathVariableResolver() {
public Object resolveVariable(QName name) {
return vars.get(name.getLocalPart());
}
});
XPathExpression expr = xp
.compile("/type/OBJECT_TYPE[. = $type]/following-sibling::prop[1]");
vars.put("type", obj.getObjectType());
NodeList objectProps = (NodeList) expr.evaluate(xmlDocument,
XPathConstants.NODESET);
System.out.println(objectProps);
for (int i = 0; i < objectProps.getLength(); i++) {
System.out.println(objectProps.item(i).getFirstChild()
.getNodeValue());
list.add(objectProps.item(i).getFirstChild().getNodeValue());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
public String convertListToString() {
StringBuilder sb = new StringBuilder();
if (list.size() > 0) {
sb.append(list.get(0));
for (int i = 1; i < list.size(); i++) {
sb.append(list.get(i));
}
}
return sb.toString();
}
}
我尝试过的第二个解决方案既不起作用也不在控制台中打印出任何内容。
public void ParserForObjectTypes() throws SAXException, IOException,
ParserConfigurationException {
try {
FileInputStream file = new FileInputStream(new File(
"xmlFiles/CoreDatamodel.xml"));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xPath.compile(
"//OBJECT_TYPE[text() = '" + obj.getObjectType()
+ "']/following-sibling::prop[1]/*").evaluate(
xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getNodeName() + " = "
+ nodeList.item(i).getTextContent());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
最佳答案
如果您想提取属于特定OBJECT_TYPE
的prop
,您可以使用
/type/OBJECT_TYPE[. = 'some type']/following-sibling::prop[1]
在 Java 中,您可以使用字符串连接动态构建此 XPath 表达式,但如果您使用的库可以支持它,那么使用 XPath 变量会更安全(您没有在问题中说明您使用哪个库)重新使用)。例如使用 javax.xml.xpath
XPath xp = XPathFactory.newInstance().newXPath();
final Map<String, Object> vars = new HashMap<String, Object>();
xp.setXPathVariableResolver(new XPathVariableResolver() {
public Object resolveVariable(QName name) {
return vars.get(name.getLocalPart());
}
});
XPathExpression expr = xp.compile("/type/OBJECT_TYPE[. = $type]/following-sibling::prop[1]");
vars.put("type", "Data");
Node dataProps = (Node)expr.evaluate(doc, XPathConstants.NODE);
vars.put("type", "SiteData");
Node siteProps = (Node)expr.evaluate(doc, XPathConstants.NODE);
// taking the value from a variable
vars.put("type", obj.getObjectType());
Node objectProps = (Node)expr.evaluate(doc, XPathConstants.NODE);
关于java - 如何在 XPath 中使用变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21258468/