XSLT : 동안 속성 값을 변경하는 방법 ?
XML 문서가 있고 속성 중 하나의 값을 변경하려고합니다.
먼저 다음을 사용하여 입력에서 출력으로 모든 것을 복사했습니다.
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
이제 "type"
라는 요소 의 속성 값을 변경하고 싶습니다 "property"
.
간단한 예제에서 테스트되었으며 잘 작동합니다.
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@type[parent::property]">
<xsl:attribute name="type">
<xsl:value-of select="'your value here'"/>
</xsl:attribute>
</xsl:template>
Tomalak의 제안을 포함하도록 편집되었습니다.
이 문제에는 고전적인 해결책이 있습니다 . ID 템플릿을 사용하고 재정의 하는 것은 가장 기본적이고 강력한 XSLT 디자인 패턴 중 하나입니다 .
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pNewType" select="'myNewType'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="property/@type">
<xsl:attribute name="type">
<xsl:value-of select="$pNewType"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
이 XML 문서에 적용되는 경우 :
<t>
<property>value1</property>
<property type="old">value2</property>
</t>
원하는 결과가 생성됩니다 .
<t>
<property>value1</property>
<property type="myNewType">value2</property>
</t>
루트 요소에 xmlns 정의가 있으면 상위 두 가지 답변이 작동하지 않습니다.
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<property type="old"/>
</html>
위의 xml에서는 모든 솔루션이 작동하지 않습니다.
가능한 해결책은 다음과 같습니다.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()[local-name()='property']/@*[local-name()='type']">
<xsl:attribute name="{name()}" namespace="{namespace-uri()}">
some new value here
</xsl:attribute>
</xsl:template>
<xsl:template match="@*|node()|comment()|processing-instruction()|text()">
<xsl:copy>
<xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
대상 속성과 일치하는 템플릿이 필요합니다.
<xsl:template match='XPath/@myAttr'>
<xsl:attribute name='myAttr'>This is the value</xsl:attribute>
</xsl:template>
이것은 이미 가지고있는 "모두 복사"에 추가 된 것입니다 (실제로 항상 XSLT에 기본적으로 존재합니다). 보다 구체적인 일치가 있으면 우선적으로 사용됩니다.
간단한 노드에서 하나의 속성을 삭제하고 싶은 비슷한 경우가 있었는데 어떤 축이 속성 이름을 읽을 수 있는지 알아낼 수 없었습니다. 결국 제가해야 할 일은
@*[name(.)!='AttributeNameToDelete']
다음 XML의 경우 :
<?xml version="1.0" encoding="utf-8"?>
<root>
<property type="foo"/>
<node id="1"/>
<property type="bar">
<sub-property/>
</property>
</root>
다음 XSLT에서 작동하도록 할 수있었습니다.
<?xml version="1.0" encoding="utf-8"?>
<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="//property">
<xsl:copy>
<xsl:attribute name="type">
<xsl:value-of select="@type"/>
<xsl:text>-added</xsl:text>
</xsl:attribute>
<xsl:copy-of select="child::*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
소스 XML 문서에 자체 네임 스페이스가있는 경우 스타일 시트에서 네임 스페이스를 선언하고 접두사를 할당 한 다음 소스 XML의 요소를 참조 할 때 해당 접두사를 사용해야합니다. 예를 들면 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
<!-- identity transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- exception-->
<xsl:template match="xhtml:property/@type">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
또는 원하는 경우 :
...
<!-- exception-->
<xsl:template match="@type[parent::xhtml:property]">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
...
ADDENDUM: In the highly unlikely case where the XML namespace is not known beforehand, you could do:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
<!-- identity transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- exception -->
<xsl:template match="*[local-name()='property']/@type">
<xsl:attribute name="type">
<xsl:text>some new value</xsl:text>
</xsl:attribute>
</xsl:template>
Of course, it's very difficult to imagine a scenario where you would know in advance that the source XML document contains an element named "property", with an attribute named "type" that needs replacing - but still not know the namespace of the document. I have added this mainly to show how your own solution could be streamlined.
I also came across same issue and i solved it as follows:
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- copy property element while only changing its type attribute -->
<xsl:template match="property">
<xsl:copy>
<xsl:attribute name="type">
<xsl:value-of select="'your value here'"/>
</xsl:attribute>
<xsl:apply-templates select="@*[not(local-name()='type')]|node()"/>
<xsl:copy>
</xsl:template>
ReferenceURL : https://stackoverflow.com/questions/615875/xslt-how-to-change-an-attribute-value-during-xslcopy
'development' 카테고리의 다른 글
VS2013 데이터베이스 프로젝트가 빌드되지 않음 (0) | 2020.12.29 |
---|---|
이러한 폴더의 공유 이름에 달러 기호가 추가 된 이유는 무엇입니까? (0) | 2020.12.29 |
vector :: iterator 또는 at ()을 사용하여 STL 벡터를 반복하는 것이 더 빠릅니다. (0) | 2020.12.29 |
NSURLConnection의 userAgent 변경 (0) | 2020.12.29 |
자바 게터 및 세터 (0) | 2020.12.29 |