빈 속성이 있는 XML 태그 제거

빈 속성이 있는 XML 태그 제거

입력 파일:

<ServiceArea type="STATE" value="DC">
    <DaylightSavingsUsed value="true"/>
    <FemtoSipProxyAddress value="10.13.123.100"/>
    <TermAuthAAAPSK value="secret1"/>
    <PDSNDOParams index="1">
        <batchEndIpAddress value="68.28.121.68"/>
        <batchSecurityParameterIndex value="5262006"/>
        <batchStartIpAddress value="68.28.121.68"/>
    </PDSNDOParams>
    <PDSNDOParams index="2">
        <batchEndIpAddress value="68.28.113.68"/>
        <batchIOSVersion value="tia-878-a"/>
        <batchStartIpAddress value="68.28.113.68"/>
    </PDSNDOParams>
    <PDSN1XParams index="1">
        <batchEndIpAddress value="68.28.121.68"/>
        <batchSecretKey value="72563130317354663167345439615433"/>
        <batchSecurityParameterIndex value="5262006"/>
        <batchStartIpAddress value="68.28.121.68"/>
    </PDSN1XParams>
    <PDSN1XParams index="2">
        <batchEndIpAddress value="68.28.113.68"/>
        <batchIOSVersion value="tia-878-1"/>
    </PDSN1XParams>
</ServiceArea>

<ServiceArea type="ZIP" value="66221">
</ServiceArea>

<ServiceArea type="FIPS" value="46081">
    <DaylightSavingsUsed value="true"/>
    <MTA_Number value="22"/>
    <BC10_Utilization value="476,487,526"/>
</ServiceArea>

<ServiceArea type="FIPS" value="01824">
</ServiceArea>

사이에 데이터가 없는 모든 행을 삭제하고 싶습니다.

<ServiceArea type=
</ServiceArea>

위 입력에서 다음을 제거해야 합니다.

<ServiceArea type="ZIP" value="66221">
</ServiceArea>

그리고

<ServiceArea type="FIPS" value="01824">
</ServiceArea>

답변1

스크립트(스타일시트라고도 함)를 xsltproc통해 XML 파일을 처리 할 수 있습니다 . xslt여기에는 xslt 스크립트와 제어 bash 스크립트가 포함됩니다. 예를 들어:

dropem.xslt

 <xsl:stylesheet version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="ServiceArea">
    <xsl:if test="count(*)>0">
      <ServiceArea>
        <xsl:copy-of select="node()"/>
      </ServiceArea>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

dropem.sh

#!/bin/bash
cat <<EOF | xsltproc dropem.xslt - | tail -n +2
<ALL>
$(cat)
</ALL>
EOF

실제 명령은 다음과 같습니다.

./dropem.sh < infile > outfile

참고: xslt스크립트에는 ServiceArea 노드와 일치하는 "템플릿" 요소가 포함되어 있으며 조건에 따라(하위 노드가 있는 경우) 이를 결과에 복사합니다.

xsltproc단일 XML 트리만 처리되므로 입력은 닫힌 태그 쌍으로 래핑되어야 합니다 . 패키징은 데이터 파일을 트리로 만듭니다. 줄 바꿈은 출력에서 ​​유지되지 않으며 출력은 ServiceArea 하위 트리 목록이기도 합니다.

<?xml ...그러나 필연적인 프리앰블 및 빈 줄 방출을 방지하기 위해 출력이 잘립니다 .xsltproc

이 접근 방식의 장점은 입력 파일 행 형식에 덜 민감하다는 것입니다. 단점은 xslt덜 일반적인 언어를 사용한다는 것입니다.

답변2

노드를 xmlstarlet감지하려는 방법에 따라 다양한 방법으로 이 작업을 수행 할 수 있습니다 .ServiceArea

  • 모든 ServiceArea"텍스트 노드" 노드를 삭제합니다.

    xmlstarlet ed -d '//ServiceArea[text()]' file.xml
    
  • ServiceArea자식이 없는 모든 노드를 제거합니다 .

    xmlstarlet ed -d '//ServiceArea[count(*)=0]' file.xml
    

둘 다 문서 형식이 올바른지에 따라 달라집니다. 예제 문서에는 여러 루트 노드가 포함되어 있으므로 이는 그렇지 않습니다. 이 문제를 해결하는 것은 쉽습니다. 예를 들어 문서의 <root>시작과 끝 부분에 추가하면 됩니다.</root>

답변3

모든 사람들은 올바른 XML 구문 분석 도구를 사용하여 xml을 편집하라고 말할 것이지만 다음은 ServiceArea 태그가 별도의 줄에 있다고 가정하는 간단한 awk 스크립트입니다.

awk '/<ServiceArea /{save = $0; next}
    save!="" {
       if(/<\/ServiceArea>/){ save = ""; next }
       print save
       save = ""
    }
    { print }'

이렇게 하면 해당 행이 표시될 때 시작 태그와 함께 저장됩니다. 다음 줄을 읽을 때 저장된 줄이 있지만 현재 줄이 끝 표시인 경우 두 줄을 모두 억제합니다. 그렇지 않으면 저장된 줄을 인쇄한 다음 현재 줄을 인쇄합니다.

관련 정보