XML 속성 값을 정리하는 방법

XML 속성 값을 정리하는 방법

다음과 같은 XML이 있습니다.

<string name="foo-bar">"bar-bar -bar"</string>
<string name="asdf_qwe-rty" translatable="false">"Lorem ipsum"</string>

이제 속성 에는 문자가 name포함될 수 없으므로 .-_

<string name="foo_bar">"bar-bar -bar"</string>
<string name="asdf_qwe_rty" translatable="false">"Lorem ipsum"</string>

을 사용하여 어떻게 할 수 있습니까 sed?

답변1

XML 문서의 형식이 올바르다고 가정하면 다음을 사용하여 모든 노드 속성에서 xmlstarlet모든 문자 발생을 바꿀 수 있습니다.-namestring_

$ xmlstarlet ed -u '//string/@name' -x 'translate(.,"-","_")' file.xml
<?xml version="1.0"?>
<root>
  <string name="foo_bar">"bar-bar -bar"</string>
  <string name="asdf_qwe_rty" translatable="false">"Lorem ipsum"</string>
  <string name="_test1_">name="-test1-"</string>
  <!-- <string name="-test2-">name="-test2-"</string> -->
</root>

root( 문서 형식을 잘 만들기 위해 여기에 래퍼 노드를 추가했고 , 노드 값이나 주석 내용에 영향을 주지 않는다는 것을 보여주기 위해 몇 가지 추가 사례를 추가했습니다).

xmlstarlet표현식은 XPath 표현식을 사용하여 모든 관련 속성을 찾고 각 속성 값 에 //string/@node간단한 변환을 적용합니다 . 출력은 표준 출력에 기록됩니다.-_

답변2

sed 기반 솔루션(또는 적절한 XML 구문 분석을 수행하지 않는 다른 솔루션)은 특정 비율의 극단적인 경우에 실패합니다. 예를 들어 @Pitel의 솔루션은 다음과 같습니다.

(a) 여는 태그가 아닌 주석이나 텍스트에 있더라도 이름 속성처럼 보이는 항목을 바꿉니다.

firstname(b) 또는 이름이 지정된 속성의 내용도 변경합니다.lastname

(c) 등호 주위에 공백이 있으면 속성을 찾을 수 없습니다.

따라서 일회성 임시 사용에는 충분할 수 있지만 프로덕션 워크플로우에 포함시키지 마십시오. 프로덕션 품질의 자료가 필요한 경우 XSLT 변환을 사용하십시오. 어렵지 않습니다:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
  <xsl:mode on-no-match="shallow-copy"/>
  <xsl:template match="@name">
    <xsl:attribute name="name" select="translate(., '-', '_')"/>
  </xsl:template>
</xsl:transform>

답변3

sed -r ':a; s/(name="[^-"]*)-/\1_/; ta'

관련 정보