xpath解析

之前解析xml用的都是dom4j来解析,最近学习了使用xpath来解析xml,下面附上代码:


public String parseXPath(String xml,Map<String,String> namespaceMap,String resExpression ) throws Exception{
	  
	  
	  final Map<String,String> namespaces = namespaceMap;
	  
	  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
	  documentBuilderFactory.setNamespaceAware(true);
	  DocumentBuilder db = documentBuilderFactory.newDocumentBuilder();
	  InputSource is = new InputSource(new StringReader(xml));
	  Document restDom = db.parse(is);
	  
	  XPath xPath = XPathFactory.newInstance().newXPath();
	  xPath.setNamespaceContext(new NamespaceContext() {
		
		@SuppressWarnings("rawtypes")
		public Iterator getPrefixes(String namespaceURI) {
			// TODO Auto-generated method stub
			return null;
		}
		
		public String getPrefix(String namespaceURI) {
			// TODO Auto-generated method stub
			return null;
		}
		
		public String getNamespaceURI(String prefix) {
			String namespace = namespaces.get(prefix);
			if(prefix == null || prefix.length() == 0){
				return XMLConstants.DEFAULT_NS_PREFIX;
			}else{
				return namespace;
			}
		}
	});
	  
	  XPathExpression compile = xPath.compile(resExpression);  
	  return compile.evaluate(restDom);
  }



此处已将xml转为java字符串

String xml = 
			  "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
			  "xmlns:m56=\"http://10.29.26.34:80/PSIGW/PeopleSoftServiceListeningConnector/M562995.V1\">" +
			  "<soapenv:Header/>" +
			  "<soapenv:Body>" +
			  	"<m56:Create__CompIntfc__WK_CI_USERPORFILE>" +
			  		"<m56:OPRID>aaa@wku.edu.cn</m56:OPRID><!--登陆账号 Optional:--> " +
			  		"<m56:OPRCLASS>HCPPALL</m56:OPRCLASS><!-- 必填,固定值 Optional:-->" +
			  		"<m56:ROWSECCLASS>HCDPALL</m56:ROWSECCLASS><!-- 必填,固定值 Optional:--> " +
			  		"<m56:OPERPSWD>1234</m56:OPERPSWD><!-- 密码 Optional:--> " +
			  		"<m56:SYMBOLICID>SYSADM1</m56:SYMBOLICID><!-- 必填,固定值 Optional:--> " +
			  		"<m56:LANGUAGE_CD>ENG</m56:LANGUAGE_CD><!-- 语言 Optional:--> " +
			  		"<m56:CURRENCY_CD/> <!--Optional:--> " +
			  		"<m56:ACCTLOCK>0</m56:ACCTLOCK><!-- PS中的是否锁定账户,不是必填 Optional:--> " +
			  		"<m56:PRCSPRFLCLS>HCSPPRFL</m56:PRCSPRFLCLS><!-- 必填,固定值 Optional:--> " +
			  		"<m56:DEFAULTNAVHP>HCSPNAVHP</m56:DEFAULTNAVHP><!-- 必填,固定值 Optional:--> " +
			  		"<m56:EXPENT>0</m56:EXPENT><!--  PS中账号是否过期,默认值是0,不是必填 Optional:--> " +
			  		"<m56:USERIDALIAS/> <!--Optional:--> " +
			  		"<m56:PTALLOWSWITCHUSER/> <!--Optional:--> " +
			  		"<m56:OPERPSWDCONF>1234</m56:OPERPSWDCONF><!--   密码确认  Optional:--> " +
			  		"<m56:ROLEUSER_REASSIGN/> <!--Optional:--> " +
			  		"<m56:ROLEUSER_ASSIGN_SW/> <!--Optional:--> " +
			  		"<m56:NO_SYMBID_WARN/> <!--Optional:--> " +
			  		"<m56:PSWDEXPIRED/> <!--Optional:--> " +
			  		"<m56:MPDEFAULMP/> <!--Optional:--> " +
			  		"<m56:SERVERNAME/> <!--Optional:--> " +
			  		"<m56:WORKLIST_USER_SW/> <!--Optional:--> " +
			  		"<m56:EMAIL_USER_SW/> <!--Optional:--> " +
			  		"<m56:ROLEUSER_ALT/> <!--Optional:--> " +
			  		"<m56:ROLEUSER_SUPR/> <!--Optional:--> " +
			  		"<m56:EFFDT_FROM/> <!--Optional:--> " +
			  		"<m56:EFFDT_TO/> <!--Zero or more repetitions:-->" +
			  		"<m56:PSOPRALIAS><m56:OPRALIASTYPE>EMP</m56:OPRALIASTYPE><!--  添加的人员类型Zero or more repetitions:-->" +
			  			"<m56:PSOPRALIASFIELD><!--Optional:-->" +
			  				"<m56:ATTRVALUE>0870913</m56:ATTRVALUE><!-- 添加的人员的编码 -->" +
			  			"</m56:PSOPRALIASFIELD>" +
			  		"</m56:PSOPRALIAS> <!--Zero or more repetitions:--> " +
			  		"<m56:PSOPTIONS><!--Optional:-->" +
			  			"<m56:FROM_QUERY_RULE/><!--Optional:--><m56:FROM_DIR_RULE/>" +
			  		"</m56:PSOPTIONS> <!--Zero or more repetitions:--> " +
			  		"<m56:PSROLEUSER_VW>" +
			  			"<m56:ROLENAME_1>PeopleSoft User</m56:ROLENAME_1><!-- 角色  -->" +
			  		"</m56:PSROLEUSER_VW> <!--Zero or more repetitions:--> " +
			  		"<m56:PSUSEROTHER_VW/>" +
			  	"</m56:Create__CompIntfc__WK_CI_USERPORFILE>" +
			  "</soapenv:Body>" +
			  "</soapenv:Envelope>";


利用xpath取所需要节点的值:
String resExpression = "/soapenv:Envelope/soapenv:Body/m56:Create__CompIntfc__WK_CI_USERPORFILE/m56:PSROLEUSER_VW/m56:ROLENAME_1";
	  //String resExpression = "//m12:OPRID/text()";
	  XPathUtil httpU = new XPathUtil();
	  Map<String,String> namespaces = new HashMap<String,String>();
	  namespaces.put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
	  namespaces.put("m56", "http://10.29.26.34:80/PSIGW/PeopleSoftServiceListeningConnector/M562995.V1");
	  
	  System.out.println("Result is "+ httpU.parseXPath(xml,namespaces, resExpression));



但有的时候因为xml文本的不规范,会导致xpath按路径取不到所需要的值,这里我用了通配符来解决这个问题:


XML:

String xml = 
	  "<OutputParameters xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://xmlns.oracle.com/apps/ap/rest/MdmDataSynch/synch_company/\">"+
	  "<X_ORIG_SYSTEM_TASK_ID>41a2a3bb-bdf0-45a1-93f9-e2dc39915c6b</X_ORIG_SYSTEM_TASK_ID>"+
	  "<X_EBS_API_TASK_ID>4b77bcf0-d843-50b7-e054-0010e0765cec</X_EBS_API_TASK_ID>"+
	  "<X_RETURN_STATUS>S</X_RETURN_STATUS>"+
	  "<X_ERROR_MSG/>"+
	  "</OutputParameters>";

JAVA代码:

 String resExpression = "/*[name()='OutputParameters']/*[name()='X_RETURN_STATUS']/text()";


	   System.out.println(resExpression);
	  XPathUtil httpU = new XPathUtil();
	  Map<String,String> namespaces = new HashMap<String,String>();  
	  System.out.println("Result11 is "+ httpU.parseXPath(xml,namespaces, resExpression));





### 使用XPath解析XML和HTML文档的方法与示例 XPath 是一种用于在 XML 文档中定位和选择节点的语言。它不仅可以用于解析 XML,还可以用于解析 HTML 文档,尤其是在数据抓取和处理结构化文档时非常有用。以下是使用 XPath 解析 XML 和 HTML 文档的方法及示例。 #### 使用 Java 解析 XML 文档 在 Java 中,可以使用 `javax.xml.parsers.DocumentBuilderFactory` 和 `javax.xml.xpath.XPathFactory` 来解析 XML 文件。以下是一个完整的示例代码: ```java import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.w3c.dom.Element; public class XPathParserDemo { public static void main(String[] args) throws Exception { File inputFile = new File("input.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); XPath xPath = XPathFactory.newInstance().newXPath(); String expression = "/class/student"; NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; System.out.println("Student roll no: " + element.getAttribute("rollno")); System.out.println("First Name: " + element.getElementsByTagName("firstname").item(0).getTextContent()); System.out.println("Last Name: " + element.getElementsByTagName("lastname").item(0).getTextContent()); System.out.println("Nick Name: " + element.getElementsByTagName("nickname").item(0).getTextContent()); System.out.println("Marks: " + element.getElementsByTagName("marks").item(0).getTextContent()); } } } } ``` #### 使用 Python 解析 XML 和 HTML 文档 Python 提供了 `lxml` 库,支持使用 XPath解析 XML 和 HTML 文档。以下是一个使用 `lxml` 解析 HTML 文档的示例: ```python from lxml import html import requests # 获取网页内容 response = requests.get('https://example.com') web_content = response.content # 解析 HTML 文档 tree = html.fromstring(web_content) # 使用 XPath 提取数据 titles = tree.xpath('//h1/text()') # 输出结果 print(titles) ``` #### XPath 语法示例 XPath 提供了丰富的语法来选择和操作文档中的节点。以下是一些常见的 XPath 表达式: - `/`:从根节点开始选择。 - `//`:从文档中任意位置选择节点。 - `.`:表示当前节点。 - `..`:表示父节点。 - `@`:选择属性。 例如,使用 `//name/text()` 可以选择文档中所有 `name` 标签的文本内容 [^4]。 #### 使用 XPath 解析 HTML 的注意事项 当使用 XPath 解析 HTML 文档时,需要注意以下几点: 1. **HTML 结构的复杂性**:HTML 文档通常比 XML 文档更复杂,可能会包含不规范的标签和嵌套结构。因此,确保 XPath 表达式能够正确处理这些情况。 2. **命名空间**:如果 HTML 文档使用了命名空间,需要在 XPath 表达式中正确处理命名空间。 3. **性能优化**:对于大型文档,XPath 查询可能会比较慢,建议优化查询语句以提高性能。 #### 示例:提取 HTML 中的特定内容 假设需要从 HTML 文档中提取所有段落 (`<p>`) 标签的内容,可以使用以下 XPath 表达式: ```python paragraphs = tree.xpath('//p/text()') ``` 此表达式将提取文档中所有 `<p>` 标签内的文本内容 [^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值