source

셸에서 XPath 한 줄을 실행하는 방법?

factcode 2023. 9. 11. 22:15
반응형

셸에서 XPath 한 줄을 실행하는 방법?

및/또는Ubuntu / Cent와 같은 할 수 ?OS용으로 XPath One-liner를 실행할 수 있는 명령줄 도구가 있는 패키지가 있습니까?foo //element@attribute filename.xml아니면foo //element@attribute < filename.xml결과를 한 줄씩 돌려주는 겁니까?

저는 제가 그 일을 할 수 있게 해줄 무언가를 찾고 있습니다.apt-get install foo아니면yum install foo포장지나 기타 적응 없이 바로 작동합니다.

다음은 근접한 몇 가지 예입니다.

노코기리.만약 내가 이 포장지를 쓴다면 나는 위에서 설명한 방식으로 포장지를 부를 수 있을 것입니다.

#!/usr/bin/ruby

require 'nokogiri'

Nokogiri::XML(STDIN).xpath(ARGV[0]).each do |row|
  puts row
end

XML::XPath.이 포장지와 함께 작동합니다.

#!/usr/bin/perl

use strict;
use warnings;
use XML::XPath;

my $root = XML::XPath->new(ioref => 'STDIN');
for my $node ($root->find($ARGV[0])->get_nodelist) {
  print($node->getData, "\n");
}

xpath XML noise, XM에서:XPat가은를를mlp:::p서h-- NODE --그리고.attribute = "value".

xml_grep XML요소를 할 수 추가데할 수 .from XML::Twig는 다음과 같습니다.

편집:

echo cat //element/@attribute | xmllint --shell filename.xml다음과 유사한 노이즈를 반환합니다.xpath.

xmllint --xpath //element/@attribute filename.xmlattribute = "value".

xmllint --xpath 'string(//element/@attribute)' filename.xml내가 원하는 것을 돌려주지만, 첫 번째 일치에 대해서만.

질문을 거의 만족시키는 또 다른 솔루션을 위해 임의 XPath 식을 평가하는 데 사용할 수 있는 XSLT가 있습니다(XSLT 프로세서에서 dyn:evaluate 지원 필요).

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:dyn="http://exslt.org/dynamic" extension-element-prefixes="dyn">
  <xsl:output omit-xml-declaration="yes" indent="no" method="text"/>
  <xsl:template match="/">
    <xsl:for-each select="dyn:evaluate($pattern)">
      <xsl:value-of select="dyn:evaluate($value)"/>
      <xsl:value-of select="'&#10;'"/>
    </xsl:for-each> 
  </xsl:template>
</xsl:stylesheet>

와 함께 xsltproc --stringparam pattern //element/@attribute --stringparam value . arbitrary-xpath.xslt filename.xml.

다음 도구를 사용해 보십시오.

  • xidel(xidel): xpath3
  • xmlstarlet(xmlstarlet page) : 편집, 선택, 변환...기본적으로 설치되지 않음, xpath1
  • xmllint(man xmlint): 종종 기본적으로 설치됩니다.libxml2-utils, xpath1 ( 포장지가 가질지 확인합니다.--xpath매우 오래된 릴리스와 새 줄로 구분된 출력을 켭니다(v < 2.9.9).형로할수eh수lrsnd형e할로her--shell스위치를 바꾸다
  • xpath: perl의 모듈, xpath1을 통해 설치됨
  • xml_grep: perl의 모듈인 xpath1을 통해 설치됨(제한된 xpath 사용)
  • saxon-lint(saxon-lint): 나만의 프로젝트, @Michael Kay의 Saxon-HE Java 라이브러리 위의 래퍼, xpath3: Saxon 사용HE 9.6, XPath 3.x(+레트로 호환성)

예:

xmllint --xpath '//element/@attribute' file.xml
xmlstarlet sel -t -v "//element/@attribute" file.xml
xpath -q -e '//element/@attribute' file.xml
xidel -se '//element/@attribute' file.xml
saxon-lint --xpath '//element/@attribute' file.xml

시델도 해보실 수 있습니다.저장소의 패키지에는 없지만 웹 페이지에서 다운로드할 수 있습니다(의존 관계 없음).

이 작업에 대한 간단한 구문을 사용합니다.

xidel filename.xml -e '//element/@attribute' 

XPath 2를 지원하는 희귀한 도구 중 하나입니다.

이 매우 중 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ,python-lxml의 패키지를 하지 않아도 그렇다면 별도의 패키지를 설치하지 않고도 가능합니다.

python -c "from lxml.etree import parse; from sys import stdin; print('\n'.join(parse(stdin).xpath('//element/@attribute')))"

maven pom.xml 파일을 쿼리하기 위해 검색할 때 이 질문을 우연히 발견했습니다.그러나 다음과 같은 한계가 있었습니다.

  • 크로스 플랫폼을 실행해야 합니다.
  • 추가 모듈 설치 없이 모든 주요 리눅스 배포판에 존재해야 합니다.
  • maven pom.xml 파일과 같은 복잡한 xml 파일을 처리해야 합니다.
  • 단순 구문

저는 위의 많은 것들을 시도했지만 성공하지 못했습니다.

  • python lxml.etree가 표준 python 분포의 일부가 아닙니다.
  • xml.etree는 복잡한 maven pom.xml 파일을 잘 처리하지 못하고, 충분히 깊게 파내지 못했습니다.
  • python xml.etree가 알 수 없는 이유로 maven pom.xml 파일을 처리하지 않습니다.
  • xmllint도 작동하지 않습니다. 우분투 12.04 "xmllint: libxml 버전 20708 사용"에서 코어 덤프가 자주 발생합니다.

안정적이고 짧고 다양한 플랫폼에서 작동하며 성숙한 솔루션은 루비에 내장된 rexml lib입니다.

ruby -r rexml/document -e 'include REXML; 
     puts XPath.first(Document.new($stdin), "/project/version/text()")' < pom.xml

이것을 찾게 된 계기는 다음과 같은 기사들이었습니다.

색슨은 XPath 2.0뿐만 아니라 XQuery 1.0과 (상업용 버전의) 3.0에서도 이 작업을 수행합니다. 리눅스 패키지가 아니라 jar 파일로 제공됩니다.구문(간단한 스크립트로 쉽게 래핑할 수 있음)은

java net.sf.saxon.Query -s:source.xml -qs://element/attribute

2020년 업데이트

Saxon 10.0에는 Gizmo 도구가 포함되어 있어 명령줄에서 대화식으로 또는 일괄적으로 사용할 수 있습니다.예를들면

java net.sf.saxon.Gizmo -s:source.xml
/>show //element/@attribute
/>quit

xsh에도 관심이 있을 수 있습니다.문서를 사용하여 원하는 작업을 수행할 수 있는 대화형 모드가 특징입니다.

open 1.xml ;
ls //element/@id ;
for //p[@class="first"] echo text() ;

clacke의 답변은 훌륭하지만 당신의 소스가 일반적인 HTML이 아닌 XML로 잘 구성된 경우에만 가능하다고 생각합니다.

정상적인 웹 컨텐츠에 대해서도 동일한 작업을 수행할 수 있습니다.XML 형식이 꼭 잘 되어 있지는 않은 HTML 문서:

echo "<p>foo<div>bar</div><p>baz" | python -c "from sys import stdin; \
from lxml import html; \
print '\n'.join(html.tostring(node) for node in html.parse(stdin).xpath('//p'))"

그리고 대신 html5lib를 사용합니다(웹 브라우저와 동일한 파싱 동작을 얻을 수 있도록 하기 위해). 브라우저 파서와 마찬가지로 html5lib는 HTML 사양의 파싱 요구 사항을 준수합니다.

echo "<p>foo<div>bar</div><p>baz" | python -c "from sys import stdin; \
import html5lib; from lxml import html; \
doc = html5lib.parse(stdin, treebuilder='lxml', namespaceHTMLElements=False); \
print '\n'.join(html.tostring(node) for node in doc.xpath('//p'))

Mike와 clacke의 답변과 유사하게 pom.xml 파일에서 빌드 버전을 가져오는 python one-liner(python >= 2.5 사용)는 pom.xml 파일에 보통 dtd 또는 기본 네임스페이스가 없으므로 libxml에 잘 형성된 것처럼 보이지 않습니다.

python -c "import xml.etree.ElementTree as ET; \
  print(ET.parse(open('pom.xml')).getroot().find('\
  {http://maven.apache.org/POM/4.0.0}version').text)"

Mac 및 Linux에서 테스트되었으며 추가 패키지를 설치할 필요가 없습니다.

를 위한 lxml모든 수준에서든)로에서도:t)mysubnode XPath이 XPath다어를다 ).//intermediarynode/subnode되고, . 식이 텍스트로 평가되면 텍스트가 인쇄되고 요소로 평가되면 전체 원시 요소가 텍스트로 렌더링됩니다.또한 접두사 없이 로컬 태그 이름을 사용할 수 있는 방식으로 XML 네임스페이스를 처리하려고 합니다.는 "XPath" "XPath"를 통해 활성화됩니다.-x 네임스페이스를를합니다와 . 기본 네임스페이스를 참조해야 합니다.p:사,예://p:tagname/p:subtag

#!/usr/bin/env python3
import argparse
import os
import sys

from lxml import etree

DEFAULT_NAMESPACE_KEY = 'p'

def print_element(elem):
    if isinstance(elem, str):
        print(elem)
    elif isinstance(elem, bytes):
        print(elem.decode('utf-8'))
    else:
        print(elem.text and elem.text.strip() or etree.tostring(elem, encoding='unicode', pretty_print=True))


if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='XPATH lxml wrapper',
                                     usage="""
    Print all nodes by name in XML file:                                     
    \t{0} myfile.xml somename

    Print all nodes by XPath selector (findall: reduced subset):                                     
    \t{0} myfile.xml //itermediarynode/childnode

    Print attribute values by XPath selector 'p' maps to default namespace (xpath 1.0: extended subset):                                     
    \t{0} myfile.xml //p:itermediarynode/p:childnode/@src -x
                          
     """.format(os.path.basename(sys.argv[0])))
    parser.add_argument('xpath_file',
                        help='XPath file path')
    parser.add_argument('xpath_expression',
                        help='tag name or xpath expression')
    parser.add_argument('--force_xpath', '-x',
                        action='store_true',
                        default=False,
                        help='Use lxml.xpath (rather than findall)'
    )

    args = parser.parse_args(sys.argv[1:])
    xpath_expression = args.xpath_expression

    tree = etree.parse(args.xpath_file)

    ns = tree.getroot().nsmap

    if args.force_xpath:
        if ns.keys() and None in ns:
            ns[DEFAULT_NAMESPACE_KEY] = ns.pop(None)
        for node in tree.xpath(xpath_expression, namespaces=ns):
            print_element(node)

    elif xpath_expression.isalpha():
        for node in tree.xpath(f"//*[local-name() = '{xpath_expression}']"):
            print_element(node)
    else:
        for el in tree.findall(xpath_expression, namespaces=ns):
            print_element(el)


사용합니다.lxml— 표준 파이썬 라이브러리에 포함되지 않은 C로 작성된 빠른 XML 파서.와 함께 합니다.pip install lxml의 경우 .Linux/OSX는 .로 접두사를 붙여야 할 수 .sudo.

용도:

python3 xmlcat.py file.xml "//mynode"

lxml은 URL을 입력으로 허용할 수도 있습니다.

python3 xmlcat.py http://example.com/file.xml "//mynode" 

인클로저 노드 아래에서 URL 속성을 추출합니다.<enclosure url="http:...""..>)(-x확장 XPath 1.0 서브셋을 강제로 적용합니다.

python3 xmlcat.py xmlcat.py file.xml "//enclosure/@url" -x

구글 크롬의 Xpath

있습니다 >를 마우스 오른쪽 콘솔에서 Xpath 식을 대해 실행하려면 있습니다 실행페이지의 에서 바로 마크업관련 사항 참고 없는 tools 있습니다 your 관련 실행할 에서 실행하려면 dev if 사항 : 참고 없는 ion against an 식을 ion chrome the as by of 바로 you tools ath to chance do paste page express you : select inspect it right from web 페이지 xp 대해마크업 xp ath then ath - xp Chrome에서 페이지를 마우스 오른쪽 단추로 클릭하고 Inspect를 선택한 다음 DevTools 콘솔에서 XPath 식을 다음과 같이 붙여넣습니다.$x("//spam/eggs").

: 이 페이지의 모든 작성자 가져오기:

$x("//*[@class='user-details']/a/text()")

XML::XSHXML::XSH2 이외에도 몇 가지가 있습니다.grep- suck as 및 (다음을 포함하는) 유틸리티와 유사합니다.xml_grepxml_grep2때합니다. 은 XML 을 을 할 할 할 할 MakefileXML::Twig특히 일을 하기에 좋습니다.perl팅은이의다금더은를할때근rn때할g를uhgnseoatat팅은더근금$SHELL그리고.xmllint xstlproc제공하다.

프로그램 한 도구의 최신. 이 "2" 버전의 "2" 버전의 "2" 버전의 "2" 버전 또는 "/" 버전의 "2" 버전의 "2" 버전의 "2" 버전/" 버전을 사용해야 할 수 .perl그 자체).

되는데, 는 을 하고 과 되어야 는 에 되어 가 되어야 과 는 gem install nokogiri.

당신은 이 블로그 게시물이 유용하다고 생각할 수 있습니다.

다음은 중첩 요소 elem1, elem2에서 텍스트 한 줄로 데이터를 추출하는 xmlstarlet 사용 사례입니다(또한 네임스페이스를 처리하는 방법도 보여줍니다).

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<mydoctype xmlns="http://xml-namespace-uri" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xml-namespace-uri http://xsd-uri" format="20171221A" date="2018-05-15">

  <elem1 time="0.586" length="10.586">
      <elem2 value="cue-in" type="outro" />
  </elem1>

</mydoctype>

출력은 다음과 같습니다.

0.586 10.586 cue-in outro

이 토막글에서 -m은 중첩 요소2와 일치하며, -v는 특성 값(식 및 상대 주소 지정 포함)을 출력합니다. -o 리터럴 텍스트, -n은 새 줄을 추가합니다.

xml sel -N ns="http://xml-namespace-uri" -t -m '//ns:elem1/ns:elem2' \
 -v ../@time -o " " -v '../@time + ../@length' -o " " -v @value -o " " -v @type -n file.xml

elem1에서 더 많은 특성이 필요한 경우 다음과 같이 수행할 수 있습니다(concat() 함수도 표시).

xml sel -N ns="http://xml-namespace-uri" -t -m '//ns:elem1/ns:elem2/..' \
 -v 'concat(@time, " ", @time + @length, " ", ns:elem2/@value, " ", ns:elem2/@type)' -n file.xml

xpath와 xmlstarlet을 거의 포기하고 빠른 ad-hoc 변환기를 작성하게 된 네임스페이스(ns, -N으로 선언됨)의 (IMO 불필요) 합병증에 주목하십시오.

나의 파이썬 스크립트 xgrep.py 는 이것을 정확하게 합니다.모든 속성을 검색하려면attribute은의 elementfilename.xml ...합니다. ,과 할 할 과

xgrep.py "//element/@attribute" filename.xml ...

을 위한 는 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ 예를 들어,-c성냥을 을에는-i부품을 위해, 는는데다을다데r는을는tgd,e-l파일 이름만 출력합니다.

스크립트는 데비안 또는 우분투 패키지로 제공되지 않지만 모든 종속성은 다음과 같습니다.

BaseX 데이터베이스를 설치한 후 다음과 같이 "독립 실행형 명령줄 모드"를 사용합니다.

basex -i - //element@attribute < filename.xml

아니면

basex -i filename.xml //element@attribute

쿼리 언어는 실제로 XPath가 아닌 XQuery(3.0)이지만 XQuery는 XPath의 상위 집합이므로 XPath 쿼리를 전혀 인식하지 못하고 사용할 수 있습니다.

이 프로젝트는 상당히 새로운 프로젝트이므로, https://github.com/jeffbr13/xq 을 확인해 보십시오. 주위에 포장지가 있는 것 같습니다.lxml필요한 입니다. ( 다른 했습니다), 이 이 로 한 입니다 한 에서도 했습니다 을 했습니다 을 한 에서도 )

HTML XPath 쿼리를 위한 파이썬 한 줄이 마음에 들지 않아 직접 작성했습니다.를합니다를 설치했다고 합니다.python-lxml패키지 또는 실행됨pip install --user lxml:

function htmlxpath() { python -c 'for x in __import__("lxml.html").html.fromstring(__import__("sys").stdin.read()).xpath(__import__("sys").argv[1]): print(x)' $1 }

이를 가지고 있으면 다음 예제와 같이 사용할 수 있습니다.

> curl -s https://slashdot.org | htmlxpath '//title/text()'
Slashdot: News for nerds, stuff that matters

그 싸움에서 또 다른 목소리가 되어 죄송합니다.저는 이 스레드에 있는 모든 도구들을 시도해 보았지만, 어느 도구도 제 요구에 만족할 수 없다는 것을 발견하여 제 자신의 도구를 썼습니다.여기에서 확인하실 수 있습니다: https://github.com/charmparticle/xpe

pypi에 업로드가 되었으므로 pip3로 쉽게 설치할 수 있습니다.

sudo pip3 install xpe

설치가 완료되면 셀레늄이나 자바스크립트에서 xpath를 사용할 때 얻을 수 있는 것과 같은 수준의 유연성으로 다양한 종류의 입력에 대해 xpath 표현을 실행할 수 있습니다.네, 이것으로 HTML에 대한 xpath를 사용할 수 있습니다.

네임스페이스 선언이 상위에 존재하는 경우에도 작동하는 솔루션:

xml이 상단에 네임스페이스를 선언한 경우 답변에서 제안하는 대부분의 명령이 즉시 실행되지 않습니다.예를 들어 다음과 같습니다.

입력 xml:

<elem1 xmlns="urn:x" xmlns:prefix="urn:y">
    <elem2 attr1="false" attr2="value2">
        elem2 value
    </elem2>
    <elem2 attr1="true" attr2="value2.1">
        elem2.1 value
    </elem2>    
    <prefix:elem3>
        elem3 value
    </prefix:elem3>        
</elem1>

작동하지 않음:

xmlstarlet sel -t -v "/elem1" input.xml
# nothing printed
xmllint -xpath "/elem1" input.xml
# XPath set is empty

해결책:

# Requires >=java11 to run like below (but the code requires >=java17 for case syntax to be recognized)

# Prints the whole document
java ExtractXpath.java "/" example-inputs/input.xml

# Prints the contents and self of "elem1"
java ExtractXpath.java "/elem1" input.xml

# Prints the contents and self of "elem2" whose attr2 value is: 'value2'
java ExtractXpath.java "//elem2[@attr2='value2']" input.xml

# Prints the value of the attribute 'attr2': "value2", "value2.1"
java ExtractXpath.java "/elem1/elem2/@attr2" input.xml

# Prints the text inside elem3: "elem3 value"
java ExtractXpath.java "/elem1/elem3/text()" input.xml

# Prints the name of the matched element: "prefix:elem3"
java ExtractXpath.java "name(/elem1/elem3)" input.xml
# Same as above: "prefix:elem3"
java ExtractXpath.java "name(*/elem3)" input.xml

# Prints the count of the matched elements: 2.0
java ExtractXpath.java "count(/elem2)" input.xml


# known issue: while "//elem2" works. "//elem3" does not (it works only with: '*/elem3' )


Xpath.java 추출:


import java.io.File;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathEvaluationResult;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ExtractXpath {

    public static void main(String[] args) throws Exception {
        assertThat(args.length==2, "Wrong number of args");
        String xpath = args[0];
        File file = new File(args[1]);
             
        assertThat(file.isFile(), file.getAbsolutePath()+" is not a file.");
        FileInputStream fileIS = new FileInputStream(file);
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        Document xmlDocument = builder.parse(fileIS);
        XPath xPath = XPathFactory.newInstance().newXPath();
        String expression = xpath;
        XPathExpression xpathExpression =  xPath.compile(expression);
        
        XPathEvaluationResult xpathEvalResult =  xpathExpression.evaluateExpression(xmlDocument);
        System.out.println(applyXpathExpression(xmlDocument, xpathExpression, xpathEvalResult.type().name()));
    }

    private static String applyXpathExpression(Document xmlDocument, XPathExpression expr, String xpathTypeName) throws TransformerConfigurationException, TransformerException, XPathExpressionException {

        // see: https://www.w3.org/TR/1999/REC-xpath-19991116/#corelib
        List<String> retVal = new ArrayList();
        if(xpathTypeName.equals(XPathConstants.NODESET.getLocalPart())){ //e.g. xpath: /elem1/*
            NodeList nodeList = (NodeList)expr.evaluate(xmlDocument, XPathConstants.NODESET);
            for (int i = 0; i < nodeList.getLength(); i++) {
                retVal.add(convertNodeToString(nodeList.item(i)));
            }
        }else if(xpathTypeName.equals(XPathConstants.STRING.getLocalPart())){ //e.g. xpath: name(/elem1/*)
            retVal.add((String)expr.evaluate(xmlDocument, XPathConstants.STRING));
        }else if(xpathTypeName.equals(XPathConstants.NUMBER.getLocalPart())){ //e.g. xpath: count(/elem1/*)
            retVal.add(((Number)expr.evaluate(xmlDocument, XPathConstants.NUMBER)).toString());
        }else if(xpathTypeName.equals(XPathConstants.BOOLEAN.getLocalPart())){ //e.g. xpath: contains(elem1, 'sth')
            retVal.add(((Boolean)expr.evaluate(xmlDocument, XPathConstants.BOOLEAN)).toString());
        }else if(xpathTypeName.equals(XPathConstants.NODE.getLocalPart())){ //e.g. xpath: fixme: find one
            System.err.println("WARNING found xpathTypeName=NODE");
            retVal.add(convertNodeToString((Node)expr.evaluate(xmlDocument, XPathConstants.NODE)));
        }else{
            throw new RuntimeException("Unexpected xpath type name: "+xpathTypeName+". This should normally not happen");
        }
        return retVal.stream().map(str->"==MATCH_START==\n"+str+"\n==MATCH_END==").collect(Collectors.joining ("\n"));
        
    }
    
    private static String convertNodeToString(Node node) throws TransformerConfigurationException, TransformerException {
            short nType = node.getNodeType();
        switch (nType) {
            case Node.ATTRIBUTE_NODE , Node.TEXT_NODE -> {
                return node.getNodeValue();
            }
            case Node.ELEMENT_NODE, Node.DOCUMENT_NODE -> {
                StringWriter writer = new StringWriter();
                Transformer trans = TransformerFactory.newInstance().newTransformer();
                trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                trans.setOutputProperty(OutputKeys.INDENT, "yes");
                trans.transform(new DOMSource(node), new StreamResult(writer));
                return writer.toString();
            }
            default -> {
                System.err.println("WARNING: FIXME: Node type:"+nType+" could possibly be handled in a better way.");
                return node.getNodeValue();
            }
                
        }
    }

    
    private static void assertThat(boolean b, String msg) {
        if(!b){
            System.err.println(msg+"\n\nUSAGE: program xpath xmlFile");
            System.exit(-1);
        }
    }
}

@SuppressWarnings("unchecked")
class NamespaceResolver implements NamespaceContext {
    //Store the source document to search the namespaces
    private final Document sourceDocument;
    public NamespaceResolver(Document document) {
        sourceDocument = document;
    }

    //The lookup for the namespace uris is delegated to the stored document.
    @Override
    public String getNamespaceURI(String prefix) {
        if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
            return sourceDocument.lookupNamespaceURI(null);
        } else {
            return sourceDocument.lookupNamespaceURI(prefix);
        }
    }

    @Override
    public String getPrefix(String namespaceURI) {
        return sourceDocument.lookupPrefix(namespaceURI);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Iterator getPrefixes(String namespaceURI) {
        return null;
    }
}

그리고 단순화를 위해:

xpath-extract명령:

#!/bin/bash
java ExtractXpath.java "$1" "$2"

언급URL : https://stackoverflow.com/questions/15461737/how-to-execute-xpath-one-liners-from-shell

반응형