2011-04-29 26 views
6

Tôi không thể thay đổi thành phần trong Web.config bằng MSDeploy. My Parameters.xml file:Làm thế nào để thay đổi một phần tử XML trong một không gian tên với tệp MSDeploy Parameters.xml?

<parameterEntry 
    kind="XmlFile" 
    scope="\\web.config$" 
    match="//spring/objects/object[@id='CultureResolver']/@type" /> 

Các phần có liên quan của Web.config:

<spring> 
    <objects xmlns="http://www.springframework.net"> 

     <object id="CultureResolver" type="Spring.Globalization.Resolvers.SessionCultureResolver, Spring.Web"> 
      <!--configure for server--> 
      <property name="DefaultCulture" value="en" /> 
     </object> 
    </objects> 
</spring> 

Trả lời

7

sự cố là khai báo không gian tên trên phần tử <objects/>. Truy vấn XPath của bạn không khớp với vì không có phần tử <objects/> có vùng tên trống (đó là truy vấn tìm kiếm).

Bây giờ, xác định không gian tên XML trong XPath là một vấn đề khó khăn (trong trường hợp này nó thậm chí còn không thể), vì vậy tôi muốn đề nghị bạn sử dụng biểu thức này thay vì:

"//spring/*/*[@id='CultureResolver']/@type" 

HTH ...

+0

Rất cám ơn, cũng phù hợp với tôi! Đối với những người googling: có cùng một vấn đề với triển khai parameters.xml và Mvc.Sitemap. Do xmlns trong nút mvcSiteMap, việc nhập IIS không thể khớp với xpath như sau: "/ mvcSiteMap/mvcSiteMapNode/mvcSiteMapNode [@ title = 'My Title']/@ url". – Kirill

+0

Cách giải quyết của bạn chắc chắn đã hiệu quả và tôi đã bình chọn bạn khi tôi tìm thấy câu trả lời của bạn, nhưng gần đây tôi đã phát hiện ra rằng bạn không thể viết truy vấn XPath chỉ định các không gian tên XML một cách chính xác và thực hiện theo cách mà Web Triển khai hỗ trợ. –

7

The XPath Trick

Ví dụ của bạn hơi phức tạp một chút (lúc đầu). Nhưng truy vấn XPath này, trong khi lâu hơn nữa, nên làm việc:

//spring/*[local-name() = 'objects' and namespace-uri() = 'http://www.springframework.net']/*[@id='CultureResolver' and local-name() = 'object' and namespace-uri() = 'http://www.springframework.net']/@type 

tôi phát hiện ra thủ thuật này trong this answer đến SO câu hỏi c# - Declare namespaces within XPath expression, nhưng tôi thực sự phát hiện ra nó sau khi tôi đã đăng tải câu trả lời này (ban đầu).

Tôi đã để lại hầu hết câu trả lời ban đầu của mình bên dưới và tôi cũng đã thêm phần bổ sung về cách câu trả lời gốc của tôi sai.

My Ví dụ

tôi muốn làm điều này cho NLog; đây là một ví dụ về NLog.config tập tin của tôi:

<?xml version="1.0" encoding="utf-8" ?> 
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true"> 

    ... 

    <targets> 
    <target name="HipChat" xsi:type="MethodCall" className="DbNecromancer.Logging, DbNecromancer" methodName="SendHipChatRoomNotification"> 
     <parameter layout="1234567" name="roomId" /> 
     <parameter layout="blah-blah-blah" name="authToken" /> 
     <parameter layout="${message-layout}" name="message" /> 
     <parameter layout="${level}" name="nLogLevel" /> 
    </target> 
    </targets> 

    ... 
</nlog> 

Dưới đây là các truy vấn XPath có liên quan từ tập tin Parameters.xml mình để thay đổi layout thuộc tính của các yếu tố parameter với một giá trị của "roomId" cho name thuộc tính:

/nlog/targets/target[@name='HipChat']/parameter[@name='roomId']/@layout

Bạn có thể xác nhận rằng XPath trên không phù hợp với thuộc tính mong muốn sử dụng this free online XPath tester. Bạn cũng có thể xác nhận nó không thành công bằng cách sử dụng Web Deploy!

Nhưng tôi có thể làm việc này, cả trong trình kiểm tra trực tuyến và thông qua Triển khai web, mà không sử dụng ký tự đại diện hoặc xóa khai báo không gian tên trong NLog.config. Bí quyết là thêm tiền tố không gian tên.

Dưới đây là các dòng được sửa đổi trong NLog.cấu hình:

<nlog:nlog xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true"> 
    ... 
</nlog:nlog> 

Dưới đây là các truy vấn XPath chỉnh sửa:

/nlog:nlog/targets/target[@name='HipChat']/parameter[@name='roomId']/@layout 

Ví dụ bạn

tôi không thể có được ví dụ bạn để làm việc trong các thử nghiệm trực tuyến bằng cách thêm một tiền tố nơi ví dụ của bạn đang sử dụng không gian tên (và tôi không có dự án nào sử dụng Spring). Kết quả của các thử nghiệm khi tôi cố gắng chỉ cần thêm một tiền tố:

LỖI - Không thể đánh giá biểu thức XPath: Tiền tố phải giải quyết để một không gian tên: mùa xuân

Tuy nhiên, tôi đã có thể để có được nó để làm việc bằng cách làm như sau (trong đó Tôi nghĩ rằng có thể là 'chính xác').

Dưới đây là các dòng trong XML của bạn tôi đã thay đổi:

<spring xmlns="" xmlns:spring="http://www.springframework.net"> 
    <spring:objects> 
     ... 
    </spring:objects> 

Dưới đây là các truy vấn XPath chỉnh sửa:

/spring/spring:objects/object[@id='CultureResolver']/@type 

Tại sao 'Ví dụ của tôi' và 'Ví dụ bạn' là (Một chút) Wrong

Vấn đề, như tôi dường như (hầu như không hiểu nó), là tuyên bố một không gian tên mà không có một tiền tố là rất khác với tuyên bố một với một tiền tố.

Khai báo vùng tên có tiền tố chỉ cần khai báo vùng tên và tiền tố của nó, nhưng không thay đổi không gian tên của bất kỳ thành phần nào.

Khai báo vùng tên không có tiền tố làm cho không gian tên đó trở thành không gian tên mặc định cho cả phần tử được xác định và cho tất cả phần tử con của phần tử đó.

Vì vậy, ví dụ, bạn có thể sửa đổi dòng sau trong XML của bạn và truy vấn XPath ban đầu của bạn sẽ làm việc:

<objects xmlns:spring="http://www.springframework.net"> 

[Chỉ cần thêm tiền tố spring đến không gian tên.]

Đó là bởi vì (hoặc theo giả thuyết làm việc của tôi) thêm tiền tố vào khai báo không gian tên mà không thêm tiền tố vào phần tử objects (và tất cả các con của nó) là 'đáng kể' sửa đổi XML vì nó loại bỏ các phần tử đó khỏi không gian tên .

Để thêm một cách chính xác một tiền tố mà không sửa đổi ngữ nghĩa của XML, XML của bạn nên thực hiện như sau:

<spring> 
    <spring:objects xmlns:spring="http://www.springframework.net"> 
     <spring:object id="CultureResolver" type="Spring.Globalization.Resolvers.SessionCultureResolver, Spring.Web"> 
      <!--configure for server--> 
      <spring:property name="DefaultCulture" value="en" /> 
     </spring:object> 
    </spring:objects> 
</spring> 

Và truy vấn XPath của bạn nên được như thế này:

//spring/spring:objects/spring:object[@id='CultureResolver']/@type 

Vấn đề duy nhất là không hoạt động (trong the online tester và có thể không phải với MSDeploy).

Ở trên không có tác dụng vì các công cụ XPath yêu cầu không gian tên được đăng ký (tách biệt với không gian tên được khai báo trong chính tài liệu XML). Tuy nhiên, vì cả Web Deploy và trình kiểm tra trực tuyến dường như làm, bất kỳ khai báo nào trong phần tử gốc của tài liệu XML đều được đăng ký tự động. Và điều đó rất hữu ích vì tôi không biết cách nào để đăng ký không gian tên khi sử dụng chuyển đổi tham số Web Deploy.

Để có giải thích chi tiết hơn, hãy xem câu trả lời cho câu hỏi liên quan của tôi Do XML namespaces need to be declared in the root element to be matchable by an XPath query?.

của bạn (Corrected) Ví dụ

XML:

<spring xmlns:spring="http://www.springframework.net"> 
    <spring:objects> 
     <spring:object id="CultureResolver" type="Spring.Globalization.Resolvers.SessionCultureResolver, Spring.Web"> 
      <!--configure for server--> 
      <spring:property name="DefaultCulture" value="en" /> 
     </spring:object> 
    </spring:objects> 
</spring> 

truy vấn XPath:

//spring/spring:objects/spring:object[@id='CultureResolver']/@type 

Kết luận

Nếu bạn không nhớ các truy vấn XPath dài, sử dụng lừa ở trên cùng. Nếu không, hãy sửa đổi các khai báo vùng tên XML của bạn để chúng bao gồm một tiền tố và chúng nằm trong phần tử gốc của tài liệu XML của bạn.

+2

Bạn là một quý ông và một học giả, cảm ơn bạn. Chỉ cần cho tôi ra khỏi một điểm chặt chẽ trong một go-live. – Michael12345

Các vấn đề liên quan