셸에서 XML 문서의 기본 네임스페이스 태그에 네임스페이스 접두사를 추가하고 싶습니다.

셸에서 XML 문서의 기본 네임스페이스 태그에 네임스페이스 접두사를 추가하고 싶습니다.

XML 문서인 SVG 파일이 있습니다.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
  <defs
     id="defs2">
  <!-- a lot of stuff> </defs>
  <!-- more stuff-->
</svg>

다음 출력을 얻기 위해 기본 네임스페이스에 해당하는 모든 태그에 svg: 접두사를 추가하고 싶습니다.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg:svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
  <svg:defs
     id="defs2">
  <!-- a lot of stuff> </svg:defs>
  <!-- more stuff-->
</svg:svg>

나는 이것이 쉘의 하나 또는 여러 명령줄에서 사용될 수 있다고 확신합니다.xmllint그리고/또는xmlstarlet하지만 나는 그것을 관리할 수 없습니다.

답변1

질문하신 지 꽤 시간이 지났습니다. 그럼에도 불구하고...

xmlstarlet edit-r/ --rename작업에는 새 이름의 리터럴 값이 필요하므로 XPath 기능이 더 이상 작동하지 않습니다. 그러나 xmlstarlet select 편집 명령을 생성하기 위한 코드 생성기로 사용할 수 있습니다.

xmlstarlet select -t \
  --var sq -o "'" -b \
  -o 'xmlstarlet edit --pf \' -n \
  -m 'set:distinct(//_:*)' \
    -o '  -r ' -v 'concat($sq,"//_:",local-name(),$sq)' \
    -o '  -v ' -v 'concat($sq,"svg:",local-name(),$sq)' -o ' \' -n \
  -b \
  -f -n \
file.xml 

어디

  • 표현식은 //_:*기본 네임스페이스의 모든 요소 노드와 일치합니다( _바로가기는 다음 위치에 있음).xmlstarlet 사용자 매뉴얼)
  • EXSLT 기능set:distinct 중복 제거
  • -o출력 문자열 리터럴, -n줄 바꿈, -f입력 경로 이름/URL(그러나 -표준 입력의 경우)
  • -b현재 컨테이너 종료( -m, --var없이 =, ao)
  • 생성된 XSLT 코드를 나열하기 전에 -C옵션 을 추가하세요.-t

산출:

xmlstarlet edit --pf \
  -r '//_:svg'  -v 'svg:svg' \
  -r '//_:defs'  -v 'svg:defs' \
file.xml

어디

  • -P/ --pf원본 형식 유지
  • 내부 편집 지원 후 -L/옵션 추가(사용자 가이드에는 없지만--inplaceeditxmlstarlet.txt)

출력을 쉘 스크립트로 실행하려면 다음을 수행하십시오.

xmlstarlet-select-command | sh -s > result.xml

EXSLT를 피하려면 대신 -m '//_:*' --sort 'A:T:-' . 출력을 파이프 uniq하거나 -m '//_:*'가능한 중복을 사용하십시오.

답변2

xmlstarlet특히 잔인한 방식으로 사용됨(올바른 xpath를 기다림)

for x in $(xmlstarlet sel -t -m "//*" -n -v "name()" file1.xml | sort | uniq); do 
    xmlstarlet ed -r "//svg:$x" -v "svg:$x" file1.xml > tmp.xml;
    mv tmp.xml file1.xml;
done

네임스페이스를 선언했으므로 svg이를 호출하여 xpath노드 이름의 리터럴 값을 변경해야 합니다.

관련 정보