XML 노드의 자식 노드를 위로 이동합니다
-
02-07-2019 - |
문제
Folling XML 파일이 있다고 상상해보십시오.
u003Ca>u003Cb>중간u003C/b> 에u003C/a>
나는 그것을 다음과 같은 것으로 변환하고 싶습니다.
u003Ca>beforemiddletu003C/a>
다시 말해서 나는 특정 노드의 모든 자식 노드를 가져 와서 순서대로 부모 노드로 이동하고 싶습니다. 이것은 "mv ./directory/*."이지만 XML 노드의 경우이 명령을 수행하는 것과 같습니다.
Unix 명령 줄 도구를 사용 하여이 작업을 수행하고 싶습니다. 강력한 명령 줄 XML 조작기 인 XMLStarlet을 사용해 보았습니다. 나는 이런 일을 시도했지만 작동하지 않습니다.
에코 " u003Ca>u003Cb>중간u003C/b> 후u003C/a> "| xmlstarlet ed -m "// b/*" ".."
업데이트 : XSLT 템플릿은 명령 줄에서 호출 할 수 있으므로 괜찮습니다.
내 목표는 'XHTML 페이지에서 링크 제거'입니다. 즉, 링크가있는 위치를 링크 태그의 내용으로 대체합니다.
해결책
실제 목표는 웹 페이지에서 링크를 제거하는 것이라면 이와 같은 스타일 시트를 사용해야합니다. <a>
요소 (XHTML을 사용하고 있다고 가정하고 있습니까?)은 단순히 템플릿을 해당 콘텐츠에 적용합니다.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:h="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="h">
<!-- Don't copy the <a> elements, just process their content -->
<xsl:template match="h:a">
<xsl:apply-templates />
</xsl:template>
<!-- identity template; copies everything by default -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
이 스타일 시트는 당신이 중첩 된 상황을 처리합니다. 이내에 그만큼 <a>
다음과 같이 유지하려는 요소 :
<p>Here is <a href="....">some <em>linked</em> text</a>.</p>
당신은 다음과 같이 나오기를 원할 것입니다.
<p>Here is some <em>linked</em> text.</p>
그리고 그것은 당신이 일반적인 부모 ( <p>
요소) 및 <a>
다음과 같은 요소
<p>Here is <em>some <a href="...">linked</a> text</em>.</p>
다른 팁
예제 입력 파일 (test.xml) :
<?xml version="1.0" encoding="UTF-8"?>
<test>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<a>before<b>middle</b>after</a>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<embedded>foo<a>before<b>middle</b>after</a>bar</embedded>
</test>
XSLT 스타일 시트 (Collapse.xsl :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
xmlstarlet을 사용하여 실행하십시오
xml tr collapse.xsl test.xml
생산 :
<?xml version="1.0"?>
<test>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<a>beforemiddleafter</a>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<embedded>foo<a>beforemiddleafter</a>bar</embedded>
</test>
스타일 시트의 첫 번째 템플릿은 기본 ID 변환입니다 (입력 XML 문서 전체를 복사합니다). 두 번째 템플릿은 구체적으로 '붕괴'하려는 요소와 일치하고 태그를 복사하고 요소의 문자열 값을 삽입합니다 (= 하강 노드의 문자열 값의 연결).
XSLT에서는 다음과 같이 쓸 수 있습니다.
<xsl:template match="a"><a><xsl:apply-templates /></a></xsl:template>
<xsl:template match="a/b"><xsl:value-of select="."/></xsl:template>
그리고 당신은 얻을 것입니다 :
<a>beforemiddleafter</a>
따라서이 작업을 수행하려면 쉬운 방법으로 XSL 스타일 시트를 만들고 XML 파일을 실행할 수 있습니다.
그러나 이것이 당신이 당신이하고 싶은 말이 아니라는 것을 알고 있습니다 (Unix 명령 줄 사용). 나는 유닉스에 대해 아무것도 모르기 때문에 다른 사람이 공란을 채울 수있을 것입니다. 위를 실행할 수있는 일종의 명령 줄 호출.
xmlstarlet 사용 :
xmlstr='<a>before<b>middle</b>after</a>'
updatestr="$(echo "$xmlstr" | xmlstarlet sel -T -t -m "/a/b" -v '../.' -n | sed -n '1{p;q;}')"
echo "$xmlstr" | xmlstarlet ed -u "/a" -v "$updatestr"
이것을 시도해 보셨습니까?
file.xml
<r>
<a>start<b>middle</b>end</a>
</r>
template.xsl
<xsl:template match="/">
<a><xsl:value-of select="r/a" /></a>
</xsl:template>
output
<a>startmiddleend</a>