문제
다음 XML이 주어지면:
<current>
<login_name>jd</login_name>
</current>
<people>
<person>
<first>John</first>
<last>Doe</last>
<login_name>jd</login_name>
</preson>
<person>
<first>Pierre</first>
<last>Spring</last>
<login_name>ps</login_name>
</preson>
</people>
현재/로그인 일치자 내에서 "John Doe"를 어떻게 얻을 수 있나요?
나는 다음을 시도했다:
<xsl:template match="current/login_name">
<xsl:value-of select="../people/first[login_name = .]"/>
<xsl:text> </xsl:text>
<xsl:value-of select="../people/last[login_name = .]"/>
</xsl:template>
해결책
사람들을 색인화하는 키를 정의하겠습니다.
<xsl:key name="people" match="person" use="login_name" />
여기서 키를 사용하면 코드가 깔끔하게 유지되지만, 자주 검색해야 하는 경우 효율성을 높이는 데 도움이 될 수도 있습니다. <person>
요소를 기반으로 한 요소 <login_name>
어린이.
주어진 형식의 이름을 반환하는 템플릿이 있습니다. <person>
:
<xsl:template match="person" mode="name">
<xsl:value-of select="concat(first, ' ', last)" />
</xsl:template>
그런 다음 나는 다음을 수행합니다.
<xsl:template match="current/login_name">
<xsl:apply-templates select="key('people', .)" mode="name" />
</xsl:template>
다른 팁
당신이 원하는 current()
기능
<xsl:template match="current/login_name">
<xsl:value-of select="../../people/person[login_name = current()]/first"/>
<xsl:text> </xsl:text>
<xsl:value-of select="../../people/person[login_name = current()]/last"/>
</xsl:template>
또는 좀 더 깔끔합니다.
<xsl:template match="current/login_name">
<xsl:for-each select="../../people/person[login_name = current()]">
<xsl:value-of select="first"/>
<xsl:text> </xsl:text>
<xsl:value-of select="last"/>
</xsl:for-each>
</xsl:template>
여러 사용자에게 액세스해야 하는 경우 제니티의 <xsl:key />
접근하다 이상적입니다.
이에 대한 나의 대안은 다음과 같습니다.
<xsl:template match="current/login_name">
<xsl:variable name="person" select="//people/person[login_name = .]" />
<xsl:value-of select="concat($person/first, ' ', $person/last)" />
</xsl:template>
우리는 선택한 것을 할당합니다 <person>
노드를 변수에 추가한 다음 concat()
이름/성을 출력하는 함수입니다.
예제 XML에도 오류가 있습니다.그만큼 <person>
노드가 다음으로 잘못 끝납니다. </preson>
(오식)
XML 문서의 전체 구조(루트 노드 등)를 알고 있다면 더 나은 솔루션이 제공될 수 있습니다.
내 생각에 그가 실제로 원한 것은 사람 노드의 일치가 아니라 "현재" 노드의 일치에서 교체하는 것이었습니다.
<xsl:variable name="login" select="//current/login_name/text()"/>
<xsl:template match="current/login_name">
<xsl:value-of select='concat(../../people/person[login_name=$login]/first," ", ../../people/person[login_name=$login]/last)'/>
</xsl:template>
내 생각을 스택에 추가하기 위해
<xsl:template match="login_name[parent::current]">
<xsl:variable name="login" select="text()"/>
<xsl:value-of select='concat(ancestor::people/child::person[login_name=$login]/child::first/text()," ",ancestor::people/child::person[login_name=$login]/child::last/text())'/>
</xsl:template>
나는 항상 내 XPath에서 더 장황하지만 더 명확한 IMHO에서 축을 명시적으로 사용하는 것을 선호합니다.
XML 문서의 나머지 부분이 어떻게 보이는지에 따라(단순한 조각이라고 가정) "ancestor::people"에 대한 참조를 제한해야 할 수도 있습니다. 예를 들어 "ancestor::people[1]"을 사용하여 첫 번째 사람으로 제한해야 할 수도 있습니다. 선조.