지정된 일부 태그의 특정 문자열을 XML 파일의 태그에 포함된 다른 문자열로 바꾸는 방법

지정된 일부 태그의 특정 문자열을 XML 파일의 태그에 포함된 다른 문자열로 바꾸는 방법

일부 지정된 태그의 특정 문자열을 XML 파일의 태그에 포함된 다른 문자열로 바꿔야 합니다.

가 나타나는 모든 항목을 검색하고, 태그 내에(다른 태그 내에) 있는 경우에만 다음 an example으로 바꿔야 합니다.<b>a test</b><a> ... </a>

  • 입력 예:
    <c>This is an example. <a>This is an example;</a></c>
    
  • 원하는 출력:
    <c>This is an example. <a>This is <b>a test;</b></a></c>
    

답변1

당신이 원하는 것 같습니다

  1. XML 문서의 노드 값 an example;에서 텍스트를 제거하고 ,/c/a
  2. /c/a이름이 지정된 노드에 b값이 있는 하위 노드를 추가합니다 a test;.

xmlstarlet셸에서 이 작업을 쉽게 수행할 수 있습니다.

xmlstarlet ed -u '/c/a' -x 'substring-before(text(), "an example;")' file.xml |
xmlstarlet ed -s '/c/a' -t elem -n 'b' -v 'a test;'

xmlstarlet질문의 예제 문서에 대한 첫 번째 호출은 /c/a노드 값에서 일부 텍스트가 제거된 다음 출력을 생성합니다.

<?xml version="1.0"?>
<c>This is an example. <a>This is </a></c>

두 번째 호출은 이 수정된 문서를 가져와 노드를 도입하여 다음을 생성합니다 /c/a/b.

<?xml version="1.0"?>
<c>This is an example. <a>This is <b>a test;</b></a></c>

이러한 xmlstarlet호출은 단일 명령으로 결합될 수 있습니다. 아래에서는 --inplace원본 문서의 내부 편집 에도 긴 옵션을 사용했습니다 (이는 설명을 위한 것일 뿐이므로 --inplace변환이 작동하는지 확인하려면 먼저 실행하지 않고 실행해야 합니다).

xmlstarlet ed --inplace \
    --update  '/c/a' -x 'substring-before(text(), "an example;")' \
    --subnode '/c/a' -t elem -n 'b' -v 'a test;' file.xml

위의 내용을 일반화하여 a텍스트가 포함된 노드에서 두 가지 편집을 수행합니다 an example;(질문에서 실제로 요구되는 내용입니다).

xmlstarlet ed \
    --var paths '//a[contains(text(), "an example;")]'  \
    --update  '$paths' -x 'substring-before(text(), "an example;")' \
    --subnode '$paths' -t elem -n 'b' -v 'a test;' file.xml 

여기서 유일하게 새로운 점은 편집하려는 모든 노드의 경로를 먼저 내부 변수에 저장한다는 것입니다 $paths. 그런 다음 --update에서 이러한 경로를 참조하고 수정합니다 --subnode.

관련 정보